From 75ce9aa7bc1c8cd8df2c285b86a050e18d40f6b7 Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:43:36 +0200 Subject: [PATCH 01/45] initial implementation of nodebased steps prettier.io tsfmt --- .../spotless/extra/nodebased/NpmConfig.java | 40 +++ .../nodebased/NpmFormatterStepStateBase.java | 122 +++++++ .../nodebased/prettier/PrettierConfig.java | 40 +++ .../prettier/PrettierFormatterStep.java | 135 +++++++ .../prettier/options/PrettierOptions.java | 334 ++++++++++++++++++ .../prettier/options/PrettierParser.java | 34 ++ .../nodebased/tsfmt/TsFmtFormatterStep.java | 129 +++++++ .../extra/nodebased/tsfmt/TsFmtOptions.java | 239 +++++++++++++ .../extra/nodebased/tsfmt/TsFmtResult.java | 41 +++ .../nodebased/wrapper/NodeJSWrapper.java | 89 +++++ .../extra/nodebased/wrapper/Reflective.java | 285 +++++++++++++++ .../wrapper/ReflectiveObjectWrapper.java | 76 ++++ .../nodebased/wrapper/V8ArrayWrapper.java | 53 +++ .../nodebased/wrapper/V8FunctionWrapper.java | 58 +++ .../nodebased/wrapper/V8ObjectWrapper.java | 89 +++++ .../extra/nodebased/prettier/package.json | 12 + .../extra/nodebased/tsfmt/package.json | 14 + .../java/com/diffplug/spotless/JarState.java | 24 +- testlib/build.gradle | 1 + .../prettier/PrettierFormatterStepTest.java | 76 ++++ .../tsfmt/TsFmtFormatterStepTest.java | 50 +++ 21 files changed, 1932 insertions(+), 9 deletions(-) create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/NpmConfig.java create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/NpmFormatterStepStateBase.java create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierConfig.java create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStep.java create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/options/PrettierOptions.java create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/options/PrettierParser.java create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStep.java create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtOptions.java create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtResult.java create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/NodeJSWrapper.java create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/Reflective.java create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/ReflectiveObjectWrapper.java create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8ArrayWrapper.java create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8FunctionWrapper.java create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8ObjectWrapper.java create mode 100644 lib-extra/src/main/resources/com/diffplug/spotless/extra/nodebased/prettier/package.json create mode 100644 lib-extra/src/main/resources/com/diffplug/spotless/extra/nodebased/tsfmt/package.json create mode 100644 testlib/src/test/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStepTest.java create mode 100644 testlib/src/test/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStepTest.java diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/NpmConfig.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/NpmConfig.java new file mode 100644 index 0000000000..801e6002c5 --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/NpmConfig.java @@ -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.extra.nodebased; + +import java.io.Serializable; + +public 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; + } +} diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/NpmFormatterStepStateBase.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/NpmFormatterStepStateBase.java new file mode 100644 index 0000000000..ba15bb26b8 --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/NpmFormatterStepStateBase.java @@ -0,0 +1,122 @@ +/* + * 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.extra.nodebased; + +import static java.util.Objects.requireNonNull; + +import java.io.File; +import java.io.IOException; +import java.io.Serializable; +import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import com.diffplug.spotless.*; +import com.diffplug.spotless.extra.nodebased.wrapper.NodeJSWrapper; + +public abstract class NpmFormatterStepStateBase implements Serializable { + + private static final long serialVersionUID = -5849375492831208496L; + + public final JarState jarState; + + public final FileSignature nodeModulesSignature; + + public final transient File nodeModulesDir; + + public final NpmConfig npmConfig; + + public final String stepName; + + protected NpmFormatterStepStateBase(String stepName, Provisioner provisioner, NpmConfig npmConfig, File buildDir, File npm) throws IOException { + this.stepName = stepName; + this.npmConfig = npmConfig; + this.jarState = JarState.from(j2v8MavenCoordinate(), requireNonNull(provisioner)); + + this.nodeModulesDir = prepareNodeModules(buildDir, npm); + this.nodeModulesSignature = FileSignature.signAsList(this.nodeModulesDir); + + /* + + + + + */ + } + + private File prepareNodeModules(File buildDir, File npm) throws IOException { + File targetDir = new File(buildDir, "spotless-node-modules-" + stepName); + if (!targetDir.exists()) { + if (!targetDir.mkdirs()) { + throw new IOException("cannot create temp dir for node modules at " + targetDir); + } + } + File packageJsonFile = new File(targetDir, "package.json"); + Files.write(packageJsonFile.toPath(), this.npmConfig.getPackageJsonContent().getBytes(StandardCharsets.UTF_8)); + runNpmInstall(npm, targetDir); + return targetDir; + } + + private void runNpmInstall(File npm, File npmProjectDir) throws IOException { + Process npmInstall = new ProcessBuilder() + .inheritIO() + .directory(npmProjectDir) + .command(npm.getAbsolutePath(), "install") + .start(); + try { + if (npmInstall.waitFor() != 0) { + throw new IOException("Creating npm modules failed with exit code: " + npmInstall.exitValue()); + } + } catch (InterruptedException e) { + throw new IOException("Running npm install was interrupted.", e); + } + } + + protected NodeJSWrapper nodeJSWrapper() { + return new NodeJSWrapper(this.jarState.getClassLoader()); // TODO (simschla, 02.08.18): cache this instance + } + + protected File nodeModulePath() { + return new File(new File(this.nodeModulesDir, "node_modules"), this.npmConfig.getNpmModule()); + } + + private File j2V8JarFile() { + // return new File("/Users/simschla/Downloads", "j2v8_macos_x86_64-nodejs-8.2.1-SNAPSHOT.jar"); // TODO (simschla, 27.07.18): adapt + return new File("/Users/simschla/Downloads", "j2v8_macosx_x86_64-4.6.0.jar"); // TODO (simschla, 27.07.18): adapt + } + + private String j2v8MavenCoordinate() { + return "com.eclipsesource.j2v8:j2v8_" + arch() + ":4.6.0"; + } + + private String arch() { + // TODO (simschla, 10.08.18): implement + return "macosx_x86_64"; + } + + protected static String readFileFromClasspath(Class clazz, String name) { + try { + Path path = Paths.get(clazz.getResource(name).toURI()); + return new String(Files.readAllBytes(path), StandardCharsets.UTF_8); + } catch (URISyntaxException | IOException e) { + throw ThrowingEx.asRuntime(e); + } + } + + public abstract FormatterFunc createFormatterFunc(); +} diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierConfig.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierConfig.java new file mode 100644 index 0000000000..3f7d72aa19 --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierConfig.java @@ -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.extra.nodebased.prettier; + +import java.io.File; + +import com.diffplug.spotless.extra.nodebased.prettier.options.PrettierOptions; + +public class PrettierConfig { + + private final File prettierConfigPath; + + private final PrettierOptions options; + + public PrettierConfig(File prettierConfigPath, PrettierOptions options) { + this.prettierConfigPath = prettierConfigPath; + this.options = options == null ? PrettierOptions.allDefaults() : options; + } + + public File getPrettierConfigPath() { + return prettierConfigPath; + } + + public PrettierOptions getOptions() { + return options; + } +} diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStep.java new file mode 100644 index 0000000000..b8d5fe3b64 --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStep.java @@ -0,0 +1,135 @@ +/* + * 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.extra.nodebased.prettier; + +import static java.util.Arrays.asList; +import static java.util.Objects.requireNonNull; + +import java.io.File; +import java.io.IOException; +import java.io.Serializable; + +import javax.annotation.Nonnull; + +import com.diffplug.spotless.FormatterFunc; +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.Provisioner; +import com.diffplug.spotless.ThrowingEx; +import com.diffplug.spotless.extra.nodebased.NpmConfig; +import com.diffplug.spotless.extra.nodebased.NpmFormatterStepStateBase; +import com.diffplug.spotless.extra.nodebased.prettier.options.PrettierOptions; +import com.diffplug.spotless.extra.nodebased.wrapper.*; + +public class PrettierFormatterStep { + + public static final String NAME = "prettier-format"; + + public static FormatterStep create(Provisioner provisioner, File buildDir, File npm, PrettierConfig prettierConfig) { + requireNonNull(provisioner); + requireNonNull(buildDir); + requireNonNull(npm); + return FormatterStep.createLazy(NAME, + () -> new State(NAME, provisioner, buildDir, npm, prettierConfig), + State::createFormatterFunc); + } + + public static class State extends NpmFormatterStepStateBase implements Serializable { + + private static final long serialVersionUID = -3811104513825329168L; + private final PrettierConfig prettierConfig; + + public State(String stepName, Provisioner provisioner, File buildDir, File npm, PrettierConfig prettierConfig) throws IOException { + super(stepName, + provisioner, + new NpmConfig( + readFileFromClasspath(PrettierFormatterStep.class, "package.json"), + "prettier"), + buildDir, + npm); + this.prettierConfig = requireNonNull(prettierConfig); + } + + @Override + @Nonnull + public FormatterFunc createFormatterFunc() { + + try { + final NodeJSWrapper nodeJSWrapper = nodeJSWrapper(); + final V8ObjectWrapper prettier = nodeJSWrapper.require(nodeModulePath()); + + // TODO (simschla, 14.08.18): use prettier options + final PrettierOptions[] resolvedPrettierOptions = new PrettierOptions[1]; + if (this.prettierConfig.getPrettierConfigPath() != null) { + final Exception[] toThrow = new Exception[1]; + try ( + V8FunctionWrapper resolveConfigCallback = nodeJSWrapper.createNewFunction((receiver, parameters) -> { + try { + final V8ObjectWrapper configOptions = parameters.getObject(0); // why is this always null + if (configOptions == null) { + toThrow[0] = new IllegalArgumentException("Cannot find or read config file " + this.prettierConfig.getPrettierConfigPath()); + } else { + resolvedPrettierOptions[0] = PrettierOptions + .fromV8Object(configOptions) + .overrideWith(this.prettierConfig.getOptions()); + } + } catch (Exception e) { + toThrow[0] = e; + } + return receiver; + }); + V8ObjectWrapper resolveConfigOption = nodeJSWrapper.createNewObject() + .add("config", this.prettierConfig.getPrettierConfigPath().getAbsolutePath()); + V8ArrayWrapper resolveConfigParams = nodeJSWrapper.createNewArray() + .pushNull() + .push(resolveConfigOption); + V8ObjectWrapper promise = prettier.executeObjectFunction("resolveConfig", resolveConfigParams); + V8ArrayWrapper callbacks = nodeJSWrapper.createNewArray(resolveConfigCallback);) { + + promise.executeVoidFunction("then", callbacks); + + while (resolvedPrettierOptions[0] == null && toThrow[0] == null) { + nodeJSWrapper.handleMessage(); + } + + if (toThrow[0] != null) { + throw ThrowingEx.asRuntime(toThrow[0]); + } + } + } else { + resolvedPrettierOptions[0] = this.prettierConfig.getOptions(); + } + + // final V8ObjectWrapper prettierConfig = nodeJSWrapper.createNewObject() + // .add("parser", "typescript"); + + final V8ObjectWrapper prettierConfig = resolvedPrettierOptions[0].toV8Object(nodeJSWrapper); + + return FormatterFunc.Closeable.of(() -> { + System.out.println("RELEASING PRETTIER FORMATTER FUNCTION"); + asList(prettierConfig, prettier, nodeJSWrapper).forEach(ReflectiveObjectWrapper::release); + }, input -> { + try (V8ArrayWrapper formatParams = nodeJSWrapper.createNewArray(input, prettierConfig)) { + String result = prettier.executeStringFunction("format", formatParams); + return result; + } + }); + } catch (Exception e) { + throw ThrowingEx.asRuntime(e); + } + + } + } +} diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/options/PrettierOptions.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/options/PrettierOptions.java new file mode 100644 index 0000000000..8b3d2c06c4 --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/options/PrettierOptions.java @@ -0,0 +1,334 @@ +/* + * 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.extra.nodebased.prettier.options; + +import java.util.Optional; + +import com.diffplug.spotless.extra.nodebased.wrapper.NodeJSWrapper; +import com.diffplug.spotless.extra.nodebased.wrapper.V8ObjectWrapper; + +public class PrettierOptions { + + private final Integer printWidth; + + private final Integer tabWidth; + + private final Boolean useTabs; + + private final Boolean semi; + + private final Boolean singleQuote; + + // "none", "es5" or "all" + private final String trailingComma; + + private final Boolean bracketSpacing; + + private final Boolean jsxBracketSameLine; + + // "avoid", "always" + private final String arrowParens; + + private final Integer rangeStart; + + private final Integer rangeEnd; + + private final PrettierParser parser; + + // not supported + // String filePath; + + private final Boolean requirePragma; + + private final Boolean insertPragma; + + // "always", "never", "preserve" + private final String proseWrap; + + private PrettierOptions(Builder builder) { + printWidth = builder.printWidth; + tabWidth = builder.tabWidth; + useTabs = builder.useTabs; + semi = builder.semi; + singleQuote = builder.singleQuote; + trailingComma = builder.trailingComma; + bracketSpacing = builder.bracketSpacing; + jsxBracketSameLine = builder.jsxBracketSameLine; + arrowParens = builder.arrowParens; + rangeStart = builder.rangeStart; + rangeEnd = builder.rangeEnd; + parser = builder.parser; + requirePragma = builder.requirePragma; + insertPragma = builder.insertPragma; + proseWrap = builder.proseWrap; + } + + public static Builder newBuilder() { + return new Builder(); + } + + public static Builder newBuilder(PrettierOptions copy) { + Builder builder = new Builder(); + builder.printWidth = copy.getPrintWidth(); + builder.tabWidth = copy.getTabWidth(); + builder.useTabs = copy.getUseTabs(); + builder.semi = copy.getSemi(); + builder.singleQuote = copy.getSingleQuote(); + builder.trailingComma = copy.getTrailingComma(); + builder.bracketSpacing = copy.getBracketSpacing(); + builder.jsxBracketSameLine = copy.getJsxBracketSameLine(); + builder.arrowParens = copy.getArrowParens(); + builder.rangeStart = copy.getRangeStart(); + builder.rangeEnd = copy.getRangeEnd(); + builder.parser = copy.getParser(); + builder.requirePragma = copy.getRequirePragma(); + builder.insertPragma = copy.getInsertPragma(); + builder.proseWrap = copy.getProseWrap(); + return builder; + } + + public static PrettierOptions allDefaults() { + return PrettierOptions.newBuilder().build(); + } + + public Integer getPrintWidth() { + return printWidth; + } + + public Integer getTabWidth() { + return tabWidth; + } + + public Boolean getUseTabs() { + return useTabs; + } + + public Boolean getSemi() { + return semi; + } + + public Boolean getSingleQuote() { + return singleQuote; + } + + public String getTrailingComma() { + return trailingComma; + } + + public Boolean getBracketSpacing() { + return bracketSpacing; + } + + public Boolean getJsxBracketSameLine() { + return jsxBracketSameLine; + } + + public String getArrowParens() { + return arrowParens; + } + + public Integer getRangeStart() { + return rangeStart; + } + + public Integer getRangeEnd() { + return rangeEnd; + } + + public PrettierParser getParser() { + return parser; + } + + public Boolean getRequirePragma() { + return requirePragma; + } + + public Boolean getInsertPragma() { + return insertPragma; + } + + public String getProseWrap() { + return proseWrap; + } + + public static PrettierOptions fromV8Object(V8ObjectWrapper v8PrettierOptions) { + if (v8PrettierOptions == null) { + return allDefaults(); + } + Builder builder = newBuilder(); + v8PrettierOptions.getOptionalInteger("printWidth").ifPresent(builder::withPrintWidth); + v8PrettierOptions.getOptionalInteger("tabWidth").ifPresent(builder::withTabWidth); + v8PrettierOptions.getOptionalBoolean("useTabs").ifPresent(builder::withUseTabs); + v8PrettierOptions.getOptionalBoolean("semi").ifPresent(builder::withSemi); + v8PrettierOptions.getOptionalBoolean("singleQuote").ifPresent(builder::withSingleQuote); + v8PrettierOptions.getOptionalString("trailingComma").ifPresent(builder::withTrailingComma); + v8PrettierOptions.getOptionalBoolean("bracketSpacing").ifPresent(builder::withBracketSpacing); + v8PrettierOptions.getOptionalBoolean("jsxBracketSameLine").ifPresent(builder::withJsxBracketSameLine); + v8PrettierOptions.getOptionalString("arrowParens").ifPresent(builder::withArrowParens); + v8PrettierOptions.getOptionalInteger("rangeStart").ifPresent(builder::withRangeStart); + v8PrettierOptions.getOptionalInteger("rangeEnd").ifPresent(builder::withRangeEnd); + v8PrettierOptions.getOptionalString("parser").map(PrettierParser::getByParserName).ifPresent(builder::withParser); + v8PrettierOptions.getOptionalBoolean("requirePragma").ifPresent(builder::withRequirePragma); + v8PrettierOptions.getOptionalBoolean("insertPragma").ifPresent(builder::withInsertPragma); + v8PrettierOptions.getOptionalString("proseWrap").ifPresent(builder::withProseWrap); + return builder.build(); + } + + public PrettierOptions overrideWith(PrettierOptions overrides) { + if (overrides == null) { + return this; + } + final Builder builder = newBuilder(this); + Optional.ofNullable(overrides.getPrintWidth()).ifPresent(builder::withPrintWidth); + Optional.ofNullable(overrides.getTabWidth()).ifPresent(builder::withTabWidth); + Optional.ofNullable(overrides.getUseTabs()).ifPresent(builder::withUseTabs); + Optional.ofNullable(overrides.getSemi()).ifPresent(builder::withSemi); + Optional.ofNullable(overrides.getSingleQuote()).ifPresent(builder::withSingleQuote); + Optional.ofNullable(overrides.getTrailingComma()).ifPresent(builder::withTrailingComma); + Optional.ofNullable(overrides.getBracketSpacing()).ifPresent(builder::withBracketSpacing); + Optional.ofNullable(overrides.getJsxBracketSameLine()).ifPresent(builder::withJsxBracketSameLine); + Optional.ofNullable(overrides.getArrowParens()).ifPresent(builder::withArrowParens); + Optional.ofNullable(overrides.getRangeStart()).ifPresent(builder::withRangeStart); + Optional.ofNullable(overrides.getRangeEnd()).ifPresent(builder::withRangeEnd); + Optional.ofNullable(overrides.getParser()).ifPresent(builder::withParser); + Optional.ofNullable(overrides.getRequirePragma()).ifPresent(builder::withRequirePragma); + Optional.ofNullable(overrides.getInsertPragma()).ifPresent(builder::withInsertPragma); + Optional.ofNullable(overrides.getProseWrap()).ifPresent(builder::withProseWrap); + return builder.build(); + } + + public V8ObjectWrapper toV8Object(NodeJSWrapper nodeJSWrapper) { + if (nodeJSWrapper == null) { + throw new IllegalArgumentException("cannot work without nodeJSWrapper"); + } + final V8ObjectWrapper v8Object = nodeJSWrapper.createNewObject(); + Optional.ofNullable(getPrintWidth()).ifPresent(val -> v8Object.add("printWidth", val)); + Optional.ofNullable(getTabWidth()).ifPresent(val -> v8Object.add("tabWidth", val)); + Optional.ofNullable(getUseTabs()).ifPresent(val -> v8Object.add("useTabs", val)); + Optional.ofNullable(getSemi()).ifPresent(val -> v8Object.add("semi", val)); + Optional.ofNullable(getSingleQuote()).ifPresent(val -> v8Object.add("singleQuote", val)); + Optional.ofNullable(getTrailingComma()).ifPresent(val -> v8Object.add("trailingComma", val)); + Optional.ofNullable(getBracketSpacing()).ifPresent(val -> v8Object.add("bracketSpacing", val)); + Optional.ofNullable(getJsxBracketSameLine()).ifPresent(val -> v8Object.add("jsxBracketSameLine", val)); + Optional.ofNullable(getArrowParens()).ifPresent(val -> v8Object.add("arrowParens", val)); + Optional.ofNullable(getRangeStart()).ifPresent(val -> v8Object.add("rangeStart", val)); + Optional.ofNullable(getRangeEnd()).ifPresent(val -> v8Object.add("rangeEnd", val)); + Optional.ofNullable(getParser()).map(PrettierParser::parserName).ifPresent(val -> v8Object.add("parser", val)); + Optional.ofNullable(getRequirePragma()).ifPresent(val -> v8Object.add("requirePragma", val)); + Optional.ofNullable(getInsertPragma()).ifPresent(val -> v8Object.add("insertPragma", val)); + Optional.ofNullable(getProseWrap()).ifPresent(val -> v8Object.add("proseWrap", val)); + return v8Object; + } + + public static final class Builder { + private Integer printWidth; + private Integer tabWidth; + private Boolean useTabs; + private Boolean semi; + private Boolean singleQuote; + private String trailingComma; + private Boolean bracketSpacing; + private Boolean jsxBracketSameLine; + private String arrowParens; + private Integer rangeStart; + private Integer rangeEnd; + private PrettierParser parser; + private Boolean requirePragma; + private Boolean insertPragma; + private String proseWrap; + + private Builder() {} + + public Builder withPrintWidth(Integer printWidth) { + this.printWidth = printWidth; + return this; + } + + public Builder withTabWidth(Integer tabWidth) { + this.tabWidth = tabWidth; + return this; + } + + public Builder withUseTabs(Boolean useTabs) { + this.useTabs = useTabs; + return this; + } + + public Builder withSemi(Boolean semi) { + this.semi = semi; + return this; + } + + public Builder withSingleQuote(Boolean singleQuote) { + this.singleQuote = singleQuote; + return this; + } + + public Builder withTrailingComma(String trailingComma) { + this.trailingComma = trailingComma; + return this; + } + + public Builder withBracketSpacing(Boolean bracketSpacing) { + this.bracketSpacing = bracketSpacing; + return this; + } + + public Builder withJsxBracketSameLine(Boolean jsxBracketSameLine) { + this.jsxBracketSameLine = jsxBracketSameLine; + return this; + } + + public Builder withArrowParens(String arrowParens) { + this.arrowParens = arrowParens; + return this; + } + + public Builder withRangeStart(Integer rangeStart) { + this.rangeStart = rangeStart; + return this; + } + + public Builder withRangeEnd(Integer rangeEnd) { + this.rangeEnd = rangeEnd; + return this; + } + + public Builder withParser(PrettierParser parser) { + this.parser = parser; + return this; + } + + public Builder withRequirePragma(Boolean requirePragma) { + this.requirePragma = requirePragma; + return this; + } + + public Builder withInsertPragma(Boolean insertPragma) { + this.insertPragma = insertPragma; + return this; + } + + public Builder withProseWrap(String proseWrap) { + this.proseWrap = proseWrap; + return this; + } + + public PrettierOptions build() { + return new PrettierOptions(this); + } + } +} diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/options/PrettierParser.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/options/PrettierParser.java new file mode 100644 index 0000000000..45816df5eb --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/options/PrettierParser.java @@ -0,0 +1,34 @@ +/* + * 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.extra.nodebased.prettier.options; + +import java.util.Arrays; + +public enum PrettierParser { + + BABYLON, FLOW, TYPESCRIPT, POSTCSS, JSON, GRAPHQL, MARKDOWN; + + public static PrettierParser getByParserName(String parserName) { + return Arrays.stream(PrettierParser.values()) + .filter(parser -> parser.parserName().equals(parserName)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("Unknown parser " + parserName)); + } + + public String parserName() { + return name().toLowerCase(); + } +} diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStep.java new file mode 100644 index 0000000000..3a01e3818b --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStep.java @@ -0,0 +1,129 @@ +/* + * 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.extra.nodebased.tsfmt; + +import static java.util.Arrays.asList; +import static java.util.Objects.requireNonNull; + +import java.io.File; +import java.io.IOException; +import java.io.Serializable; + +import javax.annotation.Nonnull; + +import com.diffplug.spotless.FormatterFunc; +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.Provisioner; +import com.diffplug.spotless.extra.nodebased.NpmConfig; +import com.diffplug.spotless.extra.nodebased.NpmFormatterStepStateBase; +import com.diffplug.spotless.extra.nodebased.wrapper.*; + +public class TsFmtFormatterStep { + + public static final String NAME = "tsfmt-format"; + + public static FormatterStep create(Provisioner provisioner, File buildDir, File npm, TsFmtOptions tsFmtOptions) { + requireNonNull(provisioner); + requireNonNull(buildDir); + requireNonNull(npm); + requireNonNull(tsFmtOptions); + return FormatterStep.createLazy(NAME, + () -> new State(NAME, provisioner, buildDir, npm, tsFmtOptions), + State::createFormatterFunc); + } + + public static class State extends NpmFormatterStepStateBase implements Serializable { + + private static final long serialVersionUID = -3811104513825329168L; + + private final TsFmtOptions tsFmtOptions; + + public State(String stepName, Provisioner provisioner, File buildDir, File npm, TsFmtOptions tsFmtOptions) throws IOException { + super(stepName, + provisioner, + new NpmConfig( + readFileFromClasspath(TsFmtFormatterStep.class, "package.json"), + "typescript-formatter"), + buildDir, + npm); + this.tsFmtOptions = tsFmtOptions; + } + + @Override + @Nonnull + public FormatterFunc createFormatterFunc() { + + final NodeJSWrapper nodeJSWrapper = nodeJSWrapper(); + final V8ObjectWrapper tsFmt = nodeJSWrapper.require(nodeModulePath()); + + final V8ObjectWrapper tsfmtOptions = tsFmtOptions.toV8Object(nodeJSWrapper); + + final TsFmtResult[] tsFmtResult = new TsFmtResult[1]; + V8FunctionWrapper formatResultCallback = nodeJSWrapper.createNewFunction((receiver, parameters) -> { + final V8ObjectWrapper result = parameters.getObject(0); + tsFmtResult[0] = new TsFmtResult(result.getString("message"), result.getBoolean("error"), result.getString("dest")); + //result.release(); // TODO (simschla, 09.08.18): verify if release needed? + return receiver; + }); + + /* var result = { + fileName: fileName, + settings: formatSettings, + message: message, <-- string + error: error, <-- boolean + src: content, + dest: formattedCode, <-- result + } + */ + return FormatterFunc.Closeable.of(() -> { + // TODO (simschla, 09.08.18): maybe release node stuff? + System.out.println("RELEASING FORMATTER FUNCTION"); + asList(formatResultCallback, tsfmtOptions, tsFmt, nodeJSWrapper).forEach(ReflectiveObjectWrapper::release); + }, input -> { + tsFmtResult[0] = null; + + // function processString(fileName: string, content: string, opts: Options): Promise { + + try ( + V8ArrayWrapper processStringArgs = nodeJSWrapper.createNewArray("spotless-format-string.ts", input, tsfmtOptions); + V8ObjectWrapper promise = tsFmt.executeObjectFunction("processString", processStringArgs); + V8ArrayWrapper callbacks = nodeJSWrapper.createNewArray(formatResultCallback)) { + + promise.executeVoidFunction("then", callbacks); + // TODO (simschla, 14.08.18): handle promise resolving without success + + while (tsFmtResult[0] == null) { + nodeJSWrapper.handleMessage(); + } + + if (tsFmtResult[0] == null) { + throw new IllegalStateException("should never happen"); + } + if (tsFmtResult[0].isError()) { + throw new RuntimeException(tsFmtResult[0].getMessage()); + } + return tsFmtResult[0].getFormatted(); + } + + // TODO (simschla, 09.08.18): release + // callbacks.release(); + // args.release(); + // promise.release(); + + }); + } + } +} diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtOptions.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtOptions.java new file mode 100644 index 0000000000..c2ed5d5f4c --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtOptions.java @@ -0,0 +1,239 @@ +/* + * 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.extra.nodebased.tsfmt; + +import java.io.Serializable; +import java.util.Optional; + +import com.diffplug.spotless.extra.nodebased.wrapper.NodeJSWrapper; +import com.diffplug.spotless.extra.nodebased.wrapper.V8ObjectWrapper; + +public class TsFmtOptions implements Serializable { + + private final Boolean verbose; + + private final String basedir; + + private final Boolean tsconfig; + + private final String tsconfigFile; + + private final Boolean tslint; + + private final String tslintFile; + + private final Boolean editorconfig; + + private final Boolean vscode; + + private final String vscodeFile; + + private final Boolean tsfmt; + + private final String tsfmtFile; + + private TsFmtOptions(Builder builder) { + verbose = builder.verbose; + basedir = builder.basedir; + tsconfig = builder.tsconfig; + tsconfigFile = builder.tsconfigFile; + tslint = builder.tslint; + tslintFile = builder.tslintFile; + editorconfig = builder.editorconfig; + vscode = builder.vscode; + vscodeFile = builder.vscodeFile; + tsfmt = builder.tsfmt; + tsfmtFile = builder.tsfmtFile; + } + + public Boolean getVerbose() { + return verbose; + } + + public String getBasedir() { + return basedir; + } + + public Boolean getTsconfig() { + return tsconfig; + } + + public String getTsconfigFile() { + return tsconfigFile; + } + + public Boolean getTslint() { + return tslint; + } + + public String getTslintFile() { + return tslintFile; + } + + public Boolean getEditorconfig() { + return editorconfig; + } + + public Boolean getVscode() { + return vscode; + } + + public String getVscodeFile() { + return vscodeFile; + } + + public Boolean getTsfmt() { + return tsfmt; + } + + public String getTsfmtFile() { + return tsfmtFile; + } + + public V8ObjectWrapper toV8Object(NodeJSWrapper nodeJSWrapper) { + if (nodeJSWrapper == null) { + throw new IllegalArgumentException("cannot work without nodeJSWrapper"); + } + final V8ObjectWrapper v8Object = nodeJSWrapper.createNewObject() + .add("replace", false) + .add("verify", false); + Optional.ofNullable(getVerbose()).ifPresent(val -> v8Object.add("verbose", val)); + Optional.ofNullable(getBasedir()).ifPresent(val -> v8Object.add("basedir", val)); + Optional.ofNullable(getTsconfig()).ifPresent(val -> v8Object.add("tsconfig", val)); + Optional.ofNullable(getTsconfigFile()).ifPresent(val -> v8Object.add("tsconfigFile", val)); + Optional.ofNullable(getTslint()).ifPresent(val -> v8Object.add("tslint", val)); + Optional.ofNullable(getTslintFile()).ifPresent(val -> v8Object.add("tslintFile", val)); + Optional.ofNullable(getEditorconfig()).ifPresent(val -> v8Object.add("editorconfig", val)); + Optional.ofNullable(getVscode()).ifPresent(val -> v8Object.add("vscode", val)); + Optional.ofNullable(getVscodeFile()).ifPresent(val -> v8Object.add("vscodeFile", val)); + Optional.ofNullable(getTsfmt()).ifPresent(val -> v8Object.add("tsfmt", val)); + Optional.ofNullable(getTsfmtFile()).ifPresent(val -> v8Object.add("tsfmtFile", val)); + return v8Object; + } + + public static Builder newBuilder() { + return new Builder(); + } + + public static Builder newBuilder(TsFmtOptions copy) { + Builder builder = new Builder(); + builder.verbose = copy.getVerbose(); + builder.basedir = copy.getBasedir(); + builder.tsconfig = copy.getTsconfig(); + builder.tsconfigFile = copy.getTsconfigFile(); + builder.tslint = copy.getTslint(); + builder.tslintFile = copy.getTslintFile(); + builder.editorconfig = copy.getEditorconfig(); + builder.vscode = copy.getVscode(); + builder.vscodeFile = copy.getVscodeFile(); + builder.tsfmt = copy.getTsfmt(); + builder.tsfmtFile = copy.getTsfmtFile(); + return builder; + } + + public static final class Builder { + private Boolean verbose; + private String basedir; + private Boolean tsconfig = false; + private String tsconfigFile = null; + private Boolean tslint = false; + private String tslintFile = null; + private Boolean editorconfig = false; + private Boolean vscode = false; + private String vscodeFile = null; + private Boolean tsfmt = false; + private String tsfmtFile = null; + + private Builder() {} + + public Builder withVerbose(Boolean verbose) { + this.verbose = verbose; + return this; + } + + public Builder withBasedir(String basedir) { + this.basedir = basedir; + return this; + } + + public Builder withTsconfig(Boolean tsconfig) { + this.tsconfig = tsconfig; + return this; + } + + public Builder withTsconfigFile(String tsconfigFile) { + this.tsconfigFile = tsconfigFile; + return withTsconfig(tsconfigFile != null); + } + + public Builder withTslint(Boolean tslint) { + this.tslint = tslint; + return this; + } + + public Builder withTslintFile(String tslintFile) { + this.tslintFile = tslintFile; + return withTslint(tslintFile != null); + } + + public Builder withEditorconfig(Boolean editorconfig) { + this.editorconfig = editorconfig; + return this; + } + + public Builder withVscode(Boolean vscode) { + this.vscode = vscode; + return this; + } + + public Builder withVscodeFile(String vscodeFile) { + this.vscodeFile = vscodeFile; + return withVscode(vscodeFile != null); + } + + public Builder withTsfmt(Boolean tsfmt) { + this.tsfmt = tsfmt; + return this; + } + + public Builder withTsfmtFile(String tsfmtFile) { + this.tsfmtFile = tsfmtFile; + return withTsfmt(tsfmtFile != null); + } + + public TsFmtOptions build() { + return new TsFmtOptions(this); + } + } + + /* + dryRun?: Boolean; + verbose?: Boolean; x + baseDir?: string; + replace: Boolean; + verify: Boolean; + tsconfig: Boolean; + tsconfigFile: string | null; + tslint: Boolean; + tslintFile: string | null; + editorconfig: Boolean; + vscode: Boolean; + vscodeFile: string | null; + tsfmt: Boolean; + tsfmtFile: string | null; + */ + +} diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtResult.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtResult.java new file mode 100644 index 0000000000..e30f6cd790 --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtResult.java @@ -0,0 +1,41 @@ +/* + * 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.extra.nodebased.tsfmt; + +public class TsFmtResult { + + private final String message; + private final Boolean error; + private final String formatted; + + public TsFmtResult(String message, Boolean error, String formatted) { + this.message = message; + this.error = error; + this.formatted = formatted; + } + + public String getMessage() { + return message; + } + + public Boolean isError() { + return error; + } + + public String getFormatted() { + return formatted; + } +} diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/NodeJSWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/NodeJSWrapper.java new file mode 100644 index 0000000000..bd7db83692 --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/NodeJSWrapper.java @@ -0,0 +1,89 @@ +/* + * 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.extra.nodebased.wrapper; + +import java.io.File; +import java.util.Objects; + +public 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"; + + public NodeJSWrapper(ClassLoader classLoader) { + super(Reflective.withClassLoader(classLoader), + reflective -> 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 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; + } +} diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/Reflective.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/Reflective.java new file mode 100644 index 0000000000..ee895eeb73 --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/Reflective.java @@ -0,0 +1,285 @@ +/* + * 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.extra.nodebased.wrapper; + +import static java.util.Objects.requireNonNull; + +import java.lang.reflect.*; +import java.util.Arrays; +import java.util.Objects; +import java.util.StringJoiner; + +public class Reflective { + private final ClassLoader classLoader; + + public Reflective(ClassLoader classLoader) { + this.classLoader = requireNonNull(classLoader); + } + + public static Reflective withClassLoader(ClassLoader classLoader) { + return new Reflective(classLoader); + } + + public Class clazz(String className) { + try { + return this.classLoader.loadClass(className); + } catch (ClassNotFoundException e) { + throw new ReflectiveException(e); + } + } + + public Method staticMethod(String className, String methodName, Object... parameters) { + try { + final Class clazz = clazz(className); + return clazz.getDeclaredMethod(methodName, types(parameters)); + } catch (NoSuchMethodException e) { + throw new ReflectiveException(e); + } + } + + public Object invokeStaticMethod(String className, String factoryMethodName, Object... parameters) { + try { + Method m = staticMethod(className, factoryMethodName, parameters); + return m.invoke(m.getDeclaringClass(), parameters); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new ReflectiveException(e); + } + } + + public Class[] types(TypedValue[] typedValues) { + return Arrays.stream(typedValues) + .map(TypedValue::getClazz) + .toArray(Class[]::new); + } + + public Class[] types(Object[] arguments) { + return Arrays.stream(arguments) + .map(Object::getClass) + .toArray(Class[]::new); + } + + public Object invokeMethod(Object target, String methodName, Object... parameters) { + Method m = method(target, clazz(target), methodName, parameters); + try { + return m.invoke(target, parameters); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new ReflectiveException(e); + } + } + + public Object invokeMethod(Object target, String methodName, TypedValue... parameters) { + Method m = method(target, clazz(target), methodName, parameters); + try { + return m.invoke(target, objects(parameters)); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new ReflectiveException(e); + } + } + + private Method method(Object target, Class clazz, String methodName, Object[] parameters) { + try { + final Method method = findMatchingMethod(clazz, methodName, parameters); + return method; + } catch (NoSuchMethodException e) { + if (clazz.getSuperclass() != null) { + return method(target, clazz.getSuperclass(), methodName, parameters); + } else { + // try with primitives + + throw new ReflectiveException("Could not find method " + methodName + " with parameters " + parameters + " on object " + target, e); + } + } + } + + private Method method(Object target, Class clazz, String methodName, TypedValue[] parameters) { + try { + final Method method = findMatchingMethod(clazz, methodName, parameters); + return method; + } catch (NoSuchMethodException e) { + if (clazz.getSuperclass() != null) { + return method(target, clazz.getSuperclass(), methodName, parameters); + } else { + // try with primitives + + throw new ReflectiveException("Could not find method " + methodName + " with parameters " + parameters + " on object " + target, e); + } + } + } + + private Method findMatchingMethod(Class clazz, String methodName, Object[] parameters) throws NoSuchMethodException { + final Class[] origTypes = types(parameters); + try { + return clazz.getDeclaredMethod(methodName, origTypes); + } catch (NoSuchMethodException e) { + // try with primitives + final Class[] primitives = autoUnbox(origTypes); + try { + return clazz.getDeclaredMethod(methodName, primitives); + } catch (NoSuchMethodException e1) { + // didn't work either + throw e; + } + } + } + + private Method findMatchingMethod(Class clazz, String methodName, TypedValue[] parameters) throws NoSuchMethodException { + return clazz.getDeclaredMethod(methodName, types(parameters)); + } + + private Class[] autoUnbox(Class[] possiblyBoxed) { + return Arrays.stream(possiblyBoxed) + .map(clazz -> { + try { + return (Class) this.staticField(clazz, "TYPE"); + } catch (ReflectiveException e) { + // no primitive type, just keeping current clazz + return clazz; + } + }).toArray(Class[]::new); + } + + private Class clazz(Object target) { + return target.getClass(); + } + + public Object invokeConstructor(String className, TypedValue... parameters) { + try { + final Constructor constructor = constructor(className, parameters); + return constructor.newInstance(objects(parameters)); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { + throw new ReflectiveException(e); + } + } + + private Object[] objects(TypedValue[] parameters) { + return Arrays.stream(parameters) + .map(TypedValue::getObj) + .toArray(); + } + + public Object invokeConstructor(String className, Object... parameters) { + try { + final Constructor constructor = constructor(className, parameters); + return constructor.newInstance(parameters); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { + throw new ReflectiveException(e); + } + } + + private Constructor constructor(String className, TypedValue[] parameters) { + try { + final Class clazz = clazz(className); + final Constructor constructor = clazz.getDeclaredConstructor(types(parameters)); + return constructor; + } catch (NoSuchMethodException e) { + throw new ReflectiveException(e); + } + } + + private Constructor constructor(String className, Object[] parameters) { + try { + final Class clazz = clazz(className); + final Constructor constructor = clazz.getDeclaredConstructor(types(parameters)); + return constructor; + } catch (NoSuchMethodException e) { + throw new ReflectiveException(e); + } + } + + public Object createDynamicProxy(InvocationHandler invocationHandler, String... interfaceNames) { + Class[] clazzes = Arrays.stream(interfaceNames) + .map(this::clazz) + .toArray(Class[]::new); + return Proxy.newProxyInstance(this.classLoader, clazzes, invocationHandler); + } + + public Object staticField(String className, String fieldName) { + final Class clazz = clazz(className); + return staticField(clazz, fieldName); + } + + public Object staticField(Class clazz, String fieldName) { + try { + return clazz.getDeclaredField(fieldName).get(clazz); + } catch (IllegalAccessException | NoSuchFieldException e) { + throw new ReflectiveException(e); + } + } + + public TypedValue typed(String className, Object obj) { + return new TypedValue(clazz(className), obj); + } + + public static TypedValue typed(Class clazz, Object obj) { + return new TypedValue(clazz, obj); + } + + public static class TypedValue { + private final Class clazz; + private final Object obj; + + public TypedValue(Class clazz, Object obj) { + this.clazz = requireNonNull(clazz); + this.obj = requireNonNull(obj); + } + + public Class getClazz() { + return clazz; + } + + public Object getObj() { + return obj; + } + + @Override + public String toString() { + return new StringJoiner(", ", TypedValue.class.getSimpleName() + "[", "]") + .add("clazz=" + clazz) + .add("obj=" + obj) + .toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + TypedValue that = (TypedValue) o; + return Objects.equals(clazz, that.clazz) && + Objects.equals(obj, that.obj); + } + + @Override + public int hashCode() { + return Objects.hash(clazz, obj); + } + } + + public static class ReflectiveException extends RuntimeException { + public ReflectiveException(String message) { + super(message); + } + + public ReflectiveException(String message, Throwable cause) { + super(message, cause); + } + + public ReflectiveException(Throwable cause) { + super(cause); + } + } +} diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/ReflectiveObjectWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/ReflectiveObjectWrapper.java new file mode 100644 index 0000000000..a88d7a2e98 --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/ReflectiveObjectWrapper.java @@ -0,0 +1,76 @@ +/* + * 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.extra.nodebased.wrapper; + +import static java.util.Objects.requireNonNull; + +import java.util.Objects; +import java.util.function.Function; + +public abstract class ReflectiveObjectWrapper implements AutoCloseable { + + private final Object wrappedObj; + private final Reflective reflective; + + public ReflectiveObjectWrapper(Reflective reflective, Object wrappedObj) { + this.reflective = requireNonNull(reflective); + this.wrappedObj = requireNonNull(wrappedObj); + } + + public ReflectiveObjectWrapper(Reflective reflective, Function wrappedObjSupplier) { + this(reflective, wrappedObjSupplier.apply(reflective)); + } + + protected Reflective reflective() { + return this.reflective; + } + + protected Object wrappedObj() { + return this.wrappedObj; + } + + protected Object invoke(String methodName, Object... parameters) { + return reflective().invokeMethod(wrappedObj(), methodName, parameters); + } + + protected Object invoke(String methodName, Reflective.TypedValue... parameters) { + return reflective().invokeMethod(wrappedObj(), methodName, parameters); + } + + public void release() { + invoke("release"); + } + + @Override + public void close() throws Exception { + release(); + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof ReflectiveObjectWrapper)) + return false; + ReflectiveObjectWrapper that = (ReflectiveObjectWrapper) o; + return Objects.equals(wrappedObj, that.wrappedObj) && Objects.equals(getClass(), that.getClass()); + } + + @Override + public int hashCode() { + return Objects.hash(wrappedObj, getClass()); + } +} diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8ArrayWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8ArrayWrapper.java new file mode 100644 index 0000000000..fbe601c48b --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8ArrayWrapper.java @@ -0,0 +1,53 @@ +/* + * 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.extra.nodebased.wrapper; + +import static com.diffplug.spotless.extra.nodebased.wrapper.NodeJSWrapper.V8_VALUE_CLASS; + +public class V8ArrayWrapper extends ReflectiveObjectWrapper { + + public static final String WRAPPED_CLASS = "com.eclipsesource.v8.V8Array"; + + public V8ArrayWrapper(Reflective reflective, Object v8Array) { + super(reflective, v8Array); + } + + public V8ArrayWrapper push(Object object) { + if (object instanceof ReflectiveObjectWrapper) { + ReflectiveObjectWrapper objectWrapper = (ReflectiveObjectWrapper) object; + object = objectWrapper.wrappedObj(); + } + if (reflective().clazz(V8_VALUE_CLASS).isAssignableFrom(object.getClass())) { + invoke("push", reflective().typed(V8_VALUE_CLASS, object)); + } else { + invoke("push", object); + } + return this; + } + + public V8ArrayWrapper pushNull() { + invoke("pushNull"); + return this; + } + + public V8ObjectWrapper getObject(Integer index) { + Object v8Object = invoke("getObject", index); + if (v8Object == null) { + return null; + } + return new V8ObjectWrapper(this.reflective(), v8Object); + } +} diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8FunctionWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8FunctionWrapper.java new file mode 100644 index 0000000000..ed2c772eb8 --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8FunctionWrapper.java @@ -0,0 +1,58 @@ +/* + * 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.extra.nodebased.wrapper; + +import java.lang.reflect.Method; + +public class V8FunctionWrapper extends ReflectiveObjectWrapper { + + public static final String WRAPPED_CLASS = "com.eclipsesource.v8.V8Function"; + public static final String CALLBACK_WRAPPED_CLASS = "com.eclipsesource.v8.JavaCallback"; + + public V8FunctionWrapper(Reflective reflective, Object v8Function) { + super(reflective, v8Function); + } + + public static Object proxiedCallback(WrappedJavaCallback callback, Reflective reflective) { + Object proxy = reflective.createDynamicProxy((proxyInstance, method, args) -> { + if (isCallbackFunction(reflective, method, args)) { + V8ObjectWrapper receiver = new V8ObjectWrapper(reflective, args[0]); + V8ArrayWrapper parameters = new V8ArrayWrapper(reflective, args[1]); + return callback.invoke(receiver, parameters); + } + return null; + }, CALLBACK_WRAPPED_CLASS); + return reflective.clazz(CALLBACK_WRAPPED_CLASS).cast(proxy); + } + + private static boolean isCallbackFunction(Reflective reflective, Method method, Object[] args) { + if (!"invoke".equals(method.getName())) { + return false; + } + final Class[] types = reflective.types(args); + if (types.length != 2) { + return false; + } + + return V8ObjectWrapper.WRAPPED_CLASS.equals(types[0].getName()) && + V8ArrayWrapper.WRAPPED_CLASS.equals(types[1].getName()); + } + + @FunctionalInterface + public interface WrappedJavaCallback { + Object invoke(V8ObjectWrapper receiver, V8ArrayWrapper parameters); + } +} diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8ObjectWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8ObjectWrapper.java new file mode 100644 index 0000000000..4d5cadde6f --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8ObjectWrapper.java @@ -0,0 +1,89 @@ +/* + * 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.extra.nodebased.wrapper; + +import java.util.Optional; + +public class V8ObjectWrapper extends ReflectiveObjectWrapper { + + public static final String WRAPPED_CLASS = "com.eclipsesource.v8.V8Object"; + + public V8ObjectWrapper(Reflective reflective, Object v8Object) { + super(reflective, v8Object); + } + + public V8ObjectWrapper add(String name, Object value) { + invoke("add", name, value); + return this; + } + + public void executeVoidFunction(String functionName, V8ArrayWrapper params) { + invoke("executeVoidFunction", functionName, params.wrappedObj()); + } + + public V8ObjectWrapper executeObjectFunction(String functionName, V8ArrayWrapper params) { + Object returnV8Obj = invoke("executeObjectFunction", functionName, params.wrappedObj()); + return new V8ObjectWrapper(reflective(), returnV8Obj); + } + + public String executeStringFunction(String functionName, V8ArrayWrapper params) { + String returnValue = (String) invoke("executeStringFunction", functionName, params.wrappedObj()); + return returnValue; + } + + public String getString(String name) { + return (String) invoke("getString", name); + } + + public Optional getOptionalString(String name) { + String result = null; + try { + result = getString(name); + } catch (RuntimeException e) { + // ignore + } + return Optional.ofNullable(result); + } + + public boolean getBoolean(String name) { + return (boolean) invoke("getBoolean", name); + } + + public Optional getOptionalBoolean(String name) { + Boolean result = null; + try { + result = getBoolean(name); + } catch (RuntimeException e) { + // ignore + } + return Optional.ofNullable(result); + } + + public int getInteger(String name) { + return (int) invoke("getInteger", name); + } + + public Optional getOptionalInteger(String name) { + Integer result = null; + try { + result = getInteger(name); + } catch (RuntimeException e) { + // ignore + } + return Optional.ofNullable(result); + } + +} diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/nodebased/prettier/package.json b/lib-extra/src/main/resources/com/diffplug/spotless/extra/nodebased/prettier/package.json new file mode 100644 index 0000000000..94de29a49e --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/nodebased/prettier/package.json @@ -0,0 +1,12 @@ +{ + "name": "spotless-prettier-formatter-step", + "version": "1.0.0", + "devDependencies": { + "prettier": "1.13.4" + }, + "dependencies": {}, + "engines": { + "node": "8.11.2", + "npm": "5.6.0" + } +} diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/nodebased/tsfmt/package.json b/lib-extra/src/main/resources/com/diffplug/spotless/extra/nodebased/tsfmt/package.json new file mode 100644 index 0000000000..70705e2358 --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/nodebased/tsfmt/package.json @@ -0,0 +1,14 @@ +{ + "name": "spotless-tsfmt-formatter-step", + "version": "1.0.0", + "devDependencies": { + "typescript-formatter": "7.2.2", + "typescript": "2.9.2", + "tslint": "5.1.0" + }, + "dependencies": {}, + "engines": { + "node": "8.11.2", + "npm": "5.6.0" + } +} diff --git a/lib/src/main/java/com/diffplug/spotless/JarState.java b/lib/src/main/java/com/diffplug/spotless/JarState.java index faaaa43ca3..5fad56a56d 100644 --- a/lib/src/main/java/com/diffplug/spotless/JarState.java +++ b/lib/src/main/java/com/diffplug/spotless/JarState.java @@ -20,13 +20,7 @@ import java.io.Serializable; import java.net.URI; import java.net.URL; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.NoSuchElementException; -import java.util.Objects; -import java.util.Set; -import java.util.TreeSet; +import java.util.*; import java.util.stream.Collectors; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -35,7 +29,7 @@ * Grabs a jar and its dependencies from maven, * and makes it easy to access the collection in * a classloader. - * + *

* Serializes the full state of the jar, so it can * catch changes in a SNAPSHOT version. */ @@ -79,13 +73,25 @@ public static JarState from(Collection mavenCoordinates, Provisioner pro return new JarState(mavenCoordinates, fileSignature, jars); } + public static JarState fromFiles(Set jars) throws IOException { + FileSignature fileSignature = FileSignature.signAsSet(jars); + Collection identifier = identifier(jars); + return new JarState(identifier, fileSignature, jars); + } + + private static Collection identifier(Set jars) { + return jars.stream() + .map(File::getName) + .collect(Collectors.toList()); + } + URL[] jarUrls() { return jars.stream().map(File::toURI).map(ThrowingEx.wrap(URI::toURL)).toArray(URL[]::new); } /** * Returns a classloader containing only the jars in this JarState. - * + *

* The lifetime of the underlying cacheloader is controlled by {@link SpotlessCache}. */ public ClassLoader getClassLoader() { diff --git a/testlib/build.gradle b/testlib/build.gradle index 8aa81bd9a9..8783f8c744 100644 --- a/testlib/build.gradle +++ b/testlib/build.gradle @@ -4,6 +4,7 @@ apply from: rootProject.file('gradle/java-setup.gradle') dependencies { compile project(':lib') + testCompile project(':lib-extra') // TODO (simschla,10.8.2018): ok? compile "com.diffplug.durian:durian-core:${VER_DURIAN}" compile "com.diffplug.durian:durian-io:${VER_DURIAN}" compile "com.diffplug.durian:durian-testlib:${VER_DURIAN}" diff --git a/testlib/src/test/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStepTest.java b/testlib/src/test/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStepTest.java new file mode 100644 index 0000000000..efbaa45e8e --- /dev/null +++ b/testlib/src/test/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStepTest.java @@ -0,0 +1,76 @@ +/* + * 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.extra.nodebased.prettier; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +import org.junit.Test; + +import com.diffplug.spotless.*; +import com.diffplug.spotless.extra.nodebased.prettier.options.PrettierOptions; +import com.diffplug.spotless.extra.nodebased.prettier.options.PrettierParser; + +public class PrettierFormatterStepTest { + + @Test + public void testPrettierTypescript() throws IOException { + final FormatterStep formatterStep = PrettierFormatterStep.create( + TestProvisioner.mavenCentral(), + new File("/Users/simschla/tmp/demo-main/"), + new File("/Users/simschla/.nvm/versions/node/v8.11.2/bin/npm"), + new PrettierConfig(new File("/Users/simschla/tmp/.prettierrc"), + PrettierOptions.newBuilder() + .withBracketSpacing(true) + .build())); + + final Formatter formatter = Formatter.builder() + .encoding(StandardCharsets.UTF_8) + .rootDir(new File("/Users/simschla/tmp/demo-basedir").toPath()) + .lineEndingsPolicy(LineEnding.UNIX.createPolicy()) + .steps(Arrays.asList(formatterStep)) + .exceptionPolicy(FormatExceptionPolicy.failOnlyOnError()) + .build(); + + System.out.println("formatted: " + formatter.applyToAndReturnResultIfDirty(new File("/Users/simschla/tmp/demo-basedir", "example.ts"))); + } + + @Test + public void testPrettierJson() throws IOException { + final FormatterStep formatterStep = PrettierFormatterStep.create( + TestProvisioner.mavenCentral(), + new File("/Users/simschla/tmp/demo-main/"), + new File("/Users/simschla/.nvm/versions/node/v8.11.2/bin/npm"), + new PrettierConfig(new File("/Users/simschla/tmp/.prettierrc"), + PrettierOptions.newBuilder() + .withBracketSpacing(true) + .withParser(PrettierParser.JSON) + .build())); + + final Formatter formatter = Formatter.builder() + .encoding(StandardCharsets.UTF_8) + .rootDir(new File("/Users/simschla/tmp/demo-basedir").toPath()) + .lineEndingsPolicy(LineEnding.UNIX.createPolicy()) + .steps(Arrays.asList(formatterStep)) + .exceptionPolicy(FormatExceptionPolicy.failOnlyOnError()) + .build(); + + System.out.println("formatted: " + formatter.applyToAndReturnResultIfDirty(new File("/Users/simschla/tmp/demo-basedir", "toformat.json"))); + } + +} diff --git a/testlib/src/test/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStepTest.java b/testlib/src/test/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStepTest.java new file mode 100644 index 0000000000..39b49e80b2 --- /dev/null +++ b/testlib/src/test/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStepTest.java @@ -0,0 +1,50 @@ +/* + * 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.extra.nodebased.tsfmt; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +import org.junit.Test; + +import com.diffplug.spotless.*; + +public class TsFmtFormatterStepTest { + + @Test + public void testTsFmt() throws IOException { + final FormatterStep formatterStep = TsFmtFormatterStep.create( + TestProvisioner.mavenCentral(), + new File("/Users/simschla/tmp/demo-main/"), + new File("/Users/simschla/.nvm/versions/node/v8.11.2/bin/npm"), + TsFmtOptions.newBuilder() + .withBasedir("/Users/simschla/tmp/demo-basedir") + .withTslint(true) + .build()); + + final Formatter formatter = Formatter.builder() + .encoding(StandardCharsets.UTF_8) + .rootDir(new File("/Users/simschla/tmp/demo-basedir").toPath()) + .lineEndingsPolicy(LineEnding.UNIX.createPolicy()) + .steps(Arrays.asList(formatterStep)) + .exceptionPolicy(FormatExceptionPolicy.failOnlyOnError()) + .build(); + + System.out.println("formatted: " + formatter.applyToAndReturnResultIfDirty(new File("/Users/simschla/tmp/demo-basedir", "example.ts"))); + } +} From dfe881d124c9bcc2017e980d49983fee75b86249 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sun, 19 Aug 2018 22:07:56 -0700 Subject: [PATCH 02/45] Move tests for into lib-extra. - a test dependency in testlib on lib-extra causes a cyclic dependency failure in eclipse - the only reason why lib's tests are in testlib is to fix a similar cyclic concern: lib tests -> testlib testlib -> lib so our fix was to just put lib's tests into testlib's tests. That workaround is not necessary for lib-extra. --- .../extra/nodebased/prettier/PrettierFormatterStepTest.java | 0 .../spotless/extra/nodebased/tsfmt/TsFmtFormatterStepTest.java | 0 testlib/build.gradle | 1 - 3 files changed, 1 deletion(-) rename {testlib => lib-extra}/src/test/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStepTest.java (100%) rename {testlib => lib-extra}/src/test/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStepTest.java (100%) diff --git a/testlib/src/test/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStepTest.java similarity index 100% rename from testlib/src/test/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStepTest.java rename to lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStepTest.java diff --git a/testlib/src/test/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStepTest.java similarity index 100% rename from testlib/src/test/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStepTest.java rename to lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStepTest.java diff --git a/testlib/build.gradle b/testlib/build.gradle index 8783f8c744..8aa81bd9a9 100644 --- a/testlib/build.gradle +++ b/testlib/build.gradle @@ -4,7 +4,6 @@ apply from: rootProject.file('gradle/java-setup.gradle') dependencies { compile project(':lib') - testCompile project(':lib-extra') // TODO (simschla,10.8.2018): ok? compile "com.diffplug.durian:durian-core:${VER_DURIAN}" compile "com.diffplug.durian:durian-io:${VER_DURIAN}" compile "com.diffplug.durian:durian-testlib:${VER_DURIAN}" From c0bb96f0b110df0b93476952a65ee5dafc05f051 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sun, 19 Aug 2018 23:26:50 -0700 Subject: [PATCH 03/45] Separate the `NpmTest` tests from the rest of the test suite. --- lib-extra/build.gradle | 11 +++++++++++ .../diffplug/spotless/extra/nodebased/NpmTest.java | 5 +++++ .../nodebased/prettier/PrettierFormatterStepTest.java | 9 ++++++++- .../extra/nodebased/tsfmt/TsFmtFormatterStepTest.java | 3 +++ 4 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/NpmTest.java diff --git a/lib-extra/build.gradle b/lib-extra/build.gradle index bc5bcee8cc..3ba9ebffa7 100644 --- a/lib-extra/build.gradle +++ b/lib-extra/build.gradle @@ -24,3 +24,14 @@ dependencies { // we'll hold the core lib to a high standard spotbugs { reportLevel = 'low' } // low|medium|high (low = sensitive to even minor mistakes) +test { + useJUnit { + excludeCategories 'com.diffplug.spotless.extra.nodebased.NpmTest' + } +} + +task npmTest(type: Test) { + useJUnit { + includeCategories 'com.diffplug.spotless.extra.nodebased.NpmTest' + } +} diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/NpmTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/NpmTest.java new file mode 100644 index 0000000000..3653c4554b --- /dev/null +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/NpmTest.java @@ -0,0 +1,5 @@ +package com.diffplug.spotless.extra.nodebased; + +public interface NpmTest { + +} diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStepTest.java index efbaa45e8e..777d6110ee 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStepTest.java @@ -21,11 +21,18 @@ import java.util.Arrays; import org.junit.Test; +import org.junit.experimental.categories.Category; -import com.diffplug.spotless.*; +import com.diffplug.spotless.FormatExceptionPolicy; +import com.diffplug.spotless.Formatter; +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.LineEnding; +import com.diffplug.spotless.TestProvisioner; +import com.diffplug.spotless.extra.nodebased.NpmTest; import com.diffplug.spotless.extra.nodebased.prettier.options.PrettierOptions; import com.diffplug.spotless.extra.nodebased.prettier.options.PrettierParser; +@Category(NpmTest.class) public class PrettierFormatterStepTest { @Test diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStepTest.java index 39b49e80b2..730c053679 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStepTest.java @@ -21,9 +21,12 @@ import java.util.Arrays; import org.junit.Test; +import org.junit.experimental.categories.Category; import com.diffplug.spotless.*; +import com.diffplug.spotless.extra.nodebased.NpmTest; +@Category(NpmTest.class) public class TsFmtFormatterStepTest { @Test From 991457cd1361f4f2d62b3ef7f343863f88baced8 Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:44:30 +0200 Subject: [PATCH 04/45] renaming package nodebased -> npm --- .../spotless/extra/{nodebased => npm}/NpmConfig.java | 2 +- .../{nodebased => npm}/NpmFormatterStepStateBase.java | 4 ++-- .../{nodebased => npm}/prettier/PrettierConfig.java | 4 ++-- .../prettier/PrettierFormatterStep.java | 10 +++++----- .../prettier/options/PrettierOptions.java | 6 +++--- .../prettier/options/PrettierParser.java | 2 +- .../{nodebased => npm}/tsfmt/TsFmtFormatterStep.java | 8 ++++---- .../extra/{nodebased => npm}/tsfmt/TsFmtOptions.java | 6 +++--- .../extra/{nodebased => npm}/tsfmt/TsFmtResult.java | 2 +- .../{nodebased => npm}/wrapper/NodeJSWrapper.java | 2 +- .../extra/{nodebased => npm}/wrapper/Reflective.java | 2 +- .../wrapper/ReflectiveObjectWrapper.java | 2 +- .../{nodebased => npm}/wrapper/V8ArrayWrapper.java | 4 ++-- .../{nodebased => npm}/wrapper/V8FunctionWrapper.java | 2 +- .../{nodebased => npm}/wrapper/V8ObjectWrapper.java | 2 +- .../extra/{nodebased => npm}/prettier/package.json | 0 .../extra/{nodebased => npm}/tsfmt/package.json | 0 .../com/diffplug/spotless/extra/nodebased/NpmTest.java | 5 ----- .../java/com/diffplug/spotless/extra/npm/NpmTest.java | 5 +++++ .../prettier/PrettierFormatterStepTest.java | 8 ++++---- .../tsfmt/TsFmtFormatterStepTest.java | 4 ++-- 21 files changed, 40 insertions(+), 40 deletions(-) rename lib-extra/src/main/java/com/diffplug/spotless/extra/{nodebased => npm}/NpmConfig.java (95%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/{nodebased => npm}/NpmFormatterStepStateBase.java (97%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/{nodebased => npm}/prettier/PrettierConfig.java (88%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/{nodebased => npm}/prettier/PrettierFormatterStep.java (93%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/{nodebased => npm}/prettier/options/PrettierOptions.java (98%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/{nodebased => npm}/prettier/options/PrettierParser.java (94%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/{nodebased => npm}/tsfmt/TsFmtFormatterStep.java (94%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/{nodebased => npm}/tsfmt/TsFmtOptions.java (96%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/{nodebased => npm}/tsfmt/TsFmtResult.java (95%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/{nodebased => npm}/wrapper/NodeJSWrapper.java (98%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/{nodebased => npm}/wrapper/Reflective.java (99%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/{nodebased => npm}/wrapper/ReflectiveObjectWrapper.java (97%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/{nodebased => npm}/wrapper/V8ArrayWrapper.java (91%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/{nodebased => npm}/wrapper/V8FunctionWrapper.java (97%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/{nodebased => npm}/wrapper/V8ObjectWrapper.java (97%) rename lib-extra/src/main/resources/com/diffplug/spotless/extra/{nodebased => npm}/prettier/package.json (100%) rename lib-extra/src/main/resources/com/diffplug/spotless/extra/{nodebased => npm}/tsfmt/package.json (100%) delete mode 100644 lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/NpmTest.java create mode 100644 lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmTest.java rename lib-extra/src/test/java/com/diffplug/spotless/extra/{nodebased => npm}/prettier/PrettierFormatterStepTest.java (91%) rename lib-extra/src/test/java/com/diffplug/spotless/extra/{nodebased => npm}/tsfmt/TsFmtFormatterStepTest.java (94%) diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/NpmConfig.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmConfig.java similarity index 95% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/NpmConfig.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmConfig.java index 801e6002c5..cc6bdc0d6b 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/NpmConfig.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmConfig.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.nodebased; +package com.diffplug.spotless.extra.npm; import java.io.Serializable; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/NpmFormatterStepStateBase.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java similarity index 97% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/NpmFormatterStepStateBase.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java index ba15bb26b8..782faa403c 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/NpmFormatterStepStateBase.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.nodebased; +package com.diffplug.spotless.extra.npm; import static java.util.Objects.requireNonNull; @@ -27,7 +27,7 @@ import java.nio.file.Paths; import com.diffplug.spotless.*; -import com.diffplug.spotless.extra.nodebased.wrapper.NodeJSWrapper; +import com.diffplug.spotless.extra.npm.wrapper.NodeJSWrapper; public abstract class NpmFormatterStepStateBase implements Serializable { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierConfig.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/PrettierConfig.java similarity index 88% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierConfig.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/PrettierConfig.java index 3f7d72aa19..2cab32a2a5 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierConfig.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/PrettierConfig.java @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.nodebased.prettier; +package com.diffplug.spotless.extra.npm.prettier; import java.io.File; -import com.diffplug.spotless.extra.nodebased.prettier.options.PrettierOptions; +import com.diffplug.spotless.extra.npm.prettier.options.PrettierOptions; public class PrettierConfig { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/PrettierFormatterStep.java similarity index 93% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStep.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/PrettierFormatterStep.java index b8d5fe3b64..cafbeb64e2 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/PrettierFormatterStep.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.nodebased.prettier; +package com.diffplug.spotless.extra.npm.prettier; import static java.util.Arrays.asList; import static java.util.Objects.requireNonNull; @@ -28,10 +28,10 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.Provisioner; import com.diffplug.spotless.ThrowingEx; -import com.diffplug.spotless.extra.nodebased.NpmConfig; -import com.diffplug.spotless.extra.nodebased.NpmFormatterStepStateBase; -import com.diffplug.spotless.extra.nodebased.prettier.options.PrettierOptions; -import com.diffplug.spotless.extra.nodebased.wrapper.*; +import com.diffplug.spotless.extra.npm.NpmConfig; +import com.diffplug.spotless.extra.npm.NpmFormatterStepStateBase; +import com.diffplug.spotless.extra.npm.prettier.options.PrettierOptions; +import com.diffplug.spotless.extra.npm.wrapper.*; public class PrettierFormatterStep { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/options/PrettierOptions.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/options/PrettierOptions.java similarity index 98% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/options/PrettierOptions.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/options/PrettierOptions.java index 8b3d2c06c4..bb6f6b7694 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/options/PrettierOptions.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/options/PrettierOptions.java @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.nodebased.prettier.options; +package com.diffplug.spotless.extra.npm.prettier.options; import java.util.Optional; -import com.diffplug.spotless.extra.nodebased.wrapper.NodeJSWrapper; -import com.diffplug.spotless.extra.nodebased.wrapper.V8ObjectWrapper; +import com.diffplug.spotless.extra.npm.wrapper.NodeJSWrapper; +import com.diffplug.spotless.extra.npm.wrapper.V8ObjectWrapper; public class PrettierOptions { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/options/PrettierParser.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/options/PrettierParser.java similarity index 94% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/options/PrettierParser.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/options/PrettierParser.java index 45816df5eb..08cb9f345a 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/prettier/options/PrettierParser.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/options/PrettierParser.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.nodebased.prettier.options; +package com.diffplug.spotless.extra.npm.prettier.options; import java.util.Arrays; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtFormatterStep.java similarity index 94% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStep.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtFormatterStep.java index 3a01e3818b..aad68c3208 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtFormatterStep.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.nodebased.tsfmt; +package com.diffplug.spotless.extra.npm.tsfmt; import static java.util.Arrays.asList; import static java.util.Objects.requireNonNull; @@ -27,9 +27,9 @@ import com.diffplug.spotless.FormatterFunc; import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.Provisioner; -import com.diffplug.spotless.extra.nodebased.NpmConfig; -import com.diffplug.spotless.extra.nodebased.NpmFormatterStepStateBase; -import com.diffplug.spotless.extra.nodebased.wrapper.*; +import com.diffplug.spotless.extra.npm.NpmConfig; +import com.diffplug.spotless.extra.npm.NpmFormatterStepStateBase; +import com.diffplug.spotless.extra.npm.wrapper.*; public class TsFmtFormatterStep { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtOptions.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtOptions.java similarity index 96% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtOptions.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtOptions.java index c2ed5d5f4c..55b5184344 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtOptions.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtOptions.java @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.nodebased.tsfmt; +package com.diffplug.spotless.extra.npm.tsfmt; import java.io.Serializable; import java.util.Optional; -import com.diffplug.spotless.extra.nodebased.wrapper.NodeJSWrapper; -import com.diffplug.spotless.extra.nodebased.wrapper.V8ObjectWrapper; +import com.diffplug.spotless.extra.npm.wrapper.NodeJSWrapper; +import com.diffplug.spotless.extra.npm.wrapper.V8ObjectWrapper; public class TsFmtOptions implements Serializable { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtResult.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtResult.java similarity index 95% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtResult.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtResult.java index e30f6cd790..e56fb18bb0 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtResult.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtResult.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.nodebased.tsfmt; +package com.diffplug.spotless.extra.npm.tsfmt; public class TsFmtResult { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/NodeJSWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/NodeJSWrapper.java similarity index 98% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/NodeJSWrapper.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/NodeJSWrapper.java index bd7db83692..b09b2d499a 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/NodeJSWrapper.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/NodeJSWrapper.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.nodebased.wrapper; +package com.diffplug.spotless.extra.npm.wrapper; import java.io.File; import java.util.Objects; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/Reflective.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/Reflective.java similarity index 99% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/Reflective.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/Reflective.java index ee895eeb73..94c71aed6d 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/Reflective.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/Reflective.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.nodebased.wrapper; +package com.diffplug.spotless.extra.npm.wrapper; import static java.util.Objects.requireNonNull; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/ReflectiveObjectWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/ReflectiveObjectWrapper.java similarity index 97% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/ReflectiveObjectWrapper.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/ReflectiveObjectWrapper.java index a88d7a2e98..925ff2d57a 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/ReflectiveObjectWrapper.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/ReflectiveObjectWrapper.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.nodebased.wrapper; +package com.diffplug.spotless.extra.npm.wrapper; import static java.util.Objects.requireNonNull; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8ArrayWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/V8ArrayWrapper.java similarity index 91% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8ArrayWrapper.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/V8ArrayWrapper.java index fbe601c48b..b2b4269b06 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8ArrayWrapper.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/V8ArrayWrapper.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.nodebased.wrapper; +package com.diffplug.spotless.extra.npm.wrapper; -import static com.diffplug.spotless.extra.nodebased.wrapper.NodeJSWrapper.V8_VALUE_CLASS; +import static com.diffplug.spotless.extra.npm.wrapper.NodeJSWrapper.V8_VALUE_CLASS; public class V8ArrayWrapper extends ReflectiveObjectWrapper { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8FunctionWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/V8FunctionWrapper.java similarity index 97% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8FunctionWrapper.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/V8FunctionWrapper.java index ed2c772eb8..272a9e90a2 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8FunctionWrapper.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/V8FunctionWrapper.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.nodebased.wrapper; +package com.diffplug.spotless.extra.npm.wrapper; import java.lang.reflect.Method; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8ObjectWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/V8ObjectWrapper.java similarity index 97% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8ObjectWrapper.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/V8ObjectWrapper.java index 4d5cadde6f..946b6ff898 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/nodebased/wrapper/V8ObjectWrapper.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/V8ObjectWrapper.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.nodebased.wrapper; +package com.diffplug.spotless.extra.npm.wrapper; import java.util.Optional; diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/nodebased/prettier/package.json b/lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/prettier/package.json similarity index 100% rename from lib-extra/src/main/resources/com/diffplug/spotless/extra/nodebased/prettier/package.json rename to lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/prettier/package.json diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/nodebased/tsfmt/package.json b/lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/tsfmt/package.json similarity index 100% rename from lib-extra/src/main/resources/com/diffplug/spotless/extra/nodebased/tsfmt/package.json rename to lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/tsfmt/package.json diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/NpmTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/NpmTest.java deleted file mode 100644 index 3653c4554b..0000000000 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/NpmTest.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.diffplug.spotless.extra.nodebased; - -public interface NpmTest { - -} diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmTest.java new file mode 100644 index 0000000000..07ed5bb738 --- /dev/null +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmTest.java @@ -0,0 +1,5 @@ +package com.diffplug.spotless.extra.npm; + +public interface NpmTest { + +} diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/prettier/PrettierFormatterStepTest.java similarity index 91% rename from lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStepTest.java rename to lib-extra/src/test/java/com/diffplug/spotless/extra/npm/prettier/PrettierFormatterStepTest.java index 777d6110ee..66c33f4bd8 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/prettier/PrettierFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/prettier/PrettierFormatterStepTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.nodebased.prettier; +package com.diffplug.spotless.extra.npm.prettier; import java.io.File; import java.io.IOException; @@ -28,9 +28,9 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.LineEnding; import com.diffplug.spotless.TestProvisioner; -import com.diffplug.spotless.extra.nodebased.NpmTest; -import com.diffplug.spotless.extra.nodebased.prettier.options.PrettierOptions; -import com.diffplug.spotless.extra.nodebased.prettier.options.PrettierParser; +import com.diffplug.spotless.extra.npm.NpmTest; +import com.diffplug.spotless.extra.npm.prettier.options.PrettierOptions; +import com.diffplug.spotless.extra.npm.prettier.options.PrettierParser; @Category(NpmTest.class) public class PrettierFormatterStepTest { diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtFormatterStepTest.java similarity index 94% rename from lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStepTest.java rename to lib-extra/src/test/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtFormatterStepTest.java index 730c053679..6f403f2695 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/nodebased/tsfmt/TsFmtFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtFormatterStepTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.nodebased.tsfmt; +package com.diffplug.spotless.extra.npm.tsfmt; import java.io.File; import java.io.IOException; @@ -24,7 +24,7 @@ import org.junit.experimental.categories.Category; import com.diffplug.spotless.*; -import com.diffplug.spotless.extra.nodebased.NpmTest; +import com.diffplug.spotless.extra.npm.NpmTest; @Category(NpmTest.class) public class TsFmtFormatterStepTest { From 164f0472d54ef2609af8b4cc7c405dadc2d3714e Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:45:08 +0200 Subject: [PATCH 05/45] move subpackages to npm top-level package + spotlessApply --- lib-extra/build.gradle | 12 ++---------- .../extra/npm/{wrapper => }/NodeJSWrapper.java | 2 +- .../extra/npm/NpmFormatterStepStateBase.java | 1 - .../extra/npm/{prettier => }/PrettierConfig.java | 4 +--- .../npm/{prettier => }/PrettierFormatterStep.java | 8 ++------ .../{prettier/options => }/PrettierOptions.java | 5 +---- .../{prettier/options => }/PrettierParser.java | 2 +- .../extra/npm/{wrapper => }/Reflective.java | 2 +- .../{wrapper => }/ReflectiveObjectWrapper.java | 2 +- .../extra/npm/{tsfmt => }/TsFmtFormatterStep.java | 7 ++----- .../extra/npm/{tsfmt => }/TsFmtOptions.java | 5 +---- .../extra/npm/{tsfmt => }/TsFmtResult.java | 2 +- .../extra/npm/{wrapper => }/V8ArrayWrapper.java | 4 ++-- .../npm/{wrapper => }/V8FunctionWrapper.java | 2 +- .../extra/npm/{wrapper => }/V8ObjectWrapper.java | 2 +- .../package.json => prettier-package.json} | 0 .../{tsfmt/package.json => tsfmt-package.json} | 0 .../com/diffplug/spotless/extra/npm/NpmTest.java | 15 +++++++++++++++ .../{prettier => }/PrettierFormatterStepTest.java | 5 +---- .../npm/{tsfmt => }/TsFmtFormatterStepTest.java | 3 +-- 20 files changed, 35 insertions(+), 48 deletions(-) rename lib-extra/src/main/java/com/diffplug/spotless/extra/npm/{wrapper => }/NodeJSWrapper.java (98%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/npm/{prettier => }/PrettierConfig.java (89%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/npm/{prettier => }/PrettierFormatterStep.java (92%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/npm/{prettier/options => }/PrettierOptions.java (98%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/npm/{prettier/options => }/PrettierParser.java (94%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/npm/{wrapper => }/Reflective.java (99%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/npm/{wrapper => }/ReflectiveObjectWrapper.java (97%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/npm/{tsfmt => }/TsFmtFormatterStep.java (93%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/npm/{tsfmt => }/TsFmtOptions.java (97%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/npm/{tsfmt => }/TsFmtResult.java (95%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/npm/{wrapper => }/V8ArrayWrapper.java (92%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/npm/{wrapper => }/V8FunctionWrapper.java (97%) rename lib-extra/src/main/java/com/diffplug/spotless/extra/npm/{wrapper => }/V8ObjectWrapper.java (98%) rename lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/{prettier/package.json => prettier-package.json} (100%) rename lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/{tsfmt/package.json => tsfmt-package.json} (100%) rename lib-extra/src/test/java/com/diffplug/spotless/extra/npm/{prettier => }/PrettierFormatterStepTest.java (92%) rename lib-extra/src/test/java/com/diffplug/spotless/extra/npm/{tsfmt => }/TsFmtFormatterStepTest.java (94%) diff --git a/lib-extra/build.gradle b/lib-extra/build.gradle index 3ba9ebffa7..e7876297bc 100644 --- a/lib-extra/build.gradle +++ b/lib-extra/build.gradle @@ -24,14 +24,6 @@ dependencies { // we'll hold the core lib to a high standard spotbugs { reportLevel = 'low' } // low|medium|high (low = sensitive to even minor mistakes) -test { - useJUnit { - excludeCategories 'com.diffplug.spotless.extra.nodebased.NpmTest' - } -} +test { useJUnit { excludeCategories 'com.diffplug.spotless.extra.nodebased.NpmTest' } } -task npmTest(type: Test) { - useJUnit { - includeCategories 'com.diffplug.spotless.extra.nodebased.NpmTest' - } -} +task npmTest(type: Test) { useJUnit { includeCategories 'com.diffplug.spotless.extra.nodebased.NpmTest' } } diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/NodeJSWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NodeJSWrapper.java similarity index 98% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/NodeJSWrapper.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NodeJSWrapper.java index b09b2d499a..605d0abdcc 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/NodeJSWrapper.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NodeJSWrapper.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm.wrapper; +package com.diffplug.spotless.extra.npm; import java.io.File; import java.util.Objects; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java index 782faa403c..4caeb1ca8e 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java @@ -27,7 +27,6 @@ import java.nio.file.Paths; import com.diffplug.spotless.*; -import com.diffplug.spotless.extra.npm.wrapper.NodeJSWrapper; public abstract class NpmFormatterStepStateBase implements Serializable { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/PrettierConfig.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierConfig.java similarity index 89% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/PrettierConfig.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierConfig.java index 2cab32a2a5..fdc195c902 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/PrettierConfig.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierConfig.java @@ -13,12 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm.prettier; +package com.diffplug.spotless.extra.npm; import java.io.File; -import com.diffplug.spotless.extra.npm.prettier.options.PrettierOptions; - public class PrettierConfig { private final File prettierConfigPath; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/PrettierFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java similarity index 92% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/PrettierFormatterStep.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java index cafbeb64e2..bfdb0fbeaa 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/PrettierFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm.prettier; +package com.diffplug.spotless.extra.npm; import static java.util.Arrays.asList; import static java.util.Objects.requireNonNull; @@ -28,10 +28,6 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.Provisioner; import com.diffplug.spotless.ThrowingEx; -import com.diffplug.spotless.extra.npm.NpmConfig; -import com.diffplug.spotless.extra.npm.NpmFormatterStepStateBase; -import com.diffplug.spotless.extra.npm.prettier.options.PrettierOptions; -import com.diffplug.spotless.extra.npm.wrapper.*; public class PrettierFormatterStep { @@ -55,7 +51,7 @@ public State(String stepName, Provisioner provisioner, File buildDir, File npm, super(stepName, provisioner, new NpmConfig( - readFileFromClasspath(PrettierFormatterStep.class, "package.json"), + readFileFromClasspath(PrettierFormatterStep.class, "prettier-package.json"), "prettier"), buildDir, npm); diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/options/PrettierOptions.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierOptions.java similarity index 98% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/options/PrettierOptions.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierOptions.java index bb6f6b7694..6a8f2e2eaf 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/options/PrettierOptions.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierOptions.java @@ -13,13 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm.prettier.options; +package com.diffplug.spotless.extra.npm; import java.util.Optional; -import com.diffplug.spotless.extra.npm.wrapper.NodeJSWrapper; -import com.diffplug.spotless.extra.npm.wrapper.V8ObjectWrapper; - public class PrettierOptions { private final Integer printWidth; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/options/PrettierParser.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierParser.java similarity index 94% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/options/PrettierParser.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierParser.java index 08cb9f345a..daf1dd8f98 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/prettier/options/PrettierParser.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierParser.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm.prettier.options; +package com.diffplug.spotless.extra.npm; import java.util.Arrays; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/Reflective.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java similarity index 99% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/Reflective.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java index 94c71aed6d..c8c96b1dba 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/Reflective.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm.wrapper; +package com.diffplug.spotless.extra.npm; import static java.util.Objects.requireNonNull; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/ReflectiveObjectWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/ReflectiveObjectWrapper.java similarity index 97% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/ReflectiveObjectWrapper.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/ReflectiveObjectWrapper.java index 925ff2d57a..d0e5b56dcd 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/ReflectiveObjectWrapper.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/ReflectiveObjectWrapper.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm.wrapper; +package com.diffplug.spotless.extra.npm; import static java.util.Objects.requireNonNull; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java similarity index 93% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtFormatterStep.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java index aad68c3208..5161e6aa80 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm.tsfmt; +package com.diffplug.spotless.extra.npm; import static java.util.Arrays.asList; import static java.util.Objects.requireNonNull; @@ -27,9 +27,6 @@ import com.diffplug.spotless.FormatterFunc; import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.Provisioner; -import com.diffplug.spotless.extra.npm.NpmConfig; -import com.diffplug.spotless.extra.npm.NpmFormatterStepStateBase; -import com.diffplug.spotless.extra.npm.wrapper.*; public class TsFmtFormatterStep { @@ -55,7 +52,7 @@ public State(String stepName, Provisioner provisioner, File buildDir, File npm, super(stepName, provisioner, new NpmConfig( - readFileFromClasspath(TsFmtFormatterStep.class, "package.json"), + readFileFromClasspath(TsFmtFormatterStep.class, "tsfmt-package.json"), "typescript-formatter"), buildDir, npm); diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtOptions.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtOptions.java similarity index 97% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtOptions.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtOptions.java index 55b5184344..7b74b2ad4f 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtOptions.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtOptions.java @@ -13,14 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm.tsfmt; +package com.diffplug.spotless.extra.npm; import java.io.Serializable; import java.util.Optional; -import com.diffplug.spotless.extra.npm.wrapper.NodeJSWrapper; -import com.diffplug.spotless.extra.npm.wrapper.V8ObjectWrapper; - public class TsFmtOptions implements Serializable { private final Boolean verbose; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtResult.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtResult.java similarity index 95% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtResult.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtResult.java index e56fb18bb0..d64bdfec61 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtResult.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtResult.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm.tsfmt; +package com.diffplug.spotless.extra.npm; public class TsFmtResult { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/V8ArrayWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ArrayWrapper.java similarity index 92% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/V8ArrayWrapper.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ArrayWrapper.java index b2b4269b06..7dba2f354b 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/V8ArrayWrapper.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ArrayWrapper.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm.wrapper; +package com.diffplug.spotless.extra.npm; -import static com.diffplug.spotless.extra.npm.wrapper.NodeJSWrapper.V8_VALUE_CLASS; +import static com.diffplug.spotless.extra.npm.NodeJSWrapper.V8_VALUE_CLASS; public class V8ArrayWrapper extends ReflectiveObjectWrapper { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/V8FunctionWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8FunctionWrapper.java similarity index 97% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/V8FunctionWrapper.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8FunctionWrapper.java index 272a9e90a2..b305d5bdd3 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/V8FunctionWrapper.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8FunctionWrapper.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm.wrapper; +package com.diffplug.spotless.extra.npm; import java.lang.reflect.Method; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/V8ObjectWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectWrapper.java similarity index 98% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/V8ObjectWrapper.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectWrapper.java index 946b6ff898..95aa9bc2e0 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/wrapper/V8ObjectWrapper.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectWrapper.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm.wrapper; +package com.diffplug.spotless.extra.npm; import java.util.Optional; diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/prettier/package.json b/lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/prettier-package.json similarity index 100% rename from lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/prettier/package.json rename to lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/prettier-package.json diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/tsfmt/package.json b/lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/tsfmt-package.json similarity index 100% rename from lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/tsfmt/package.json rename to lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/tsfmt-package.json diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmTest.java index 07ed5bb738..0575b0f04a 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmTest.java @@ -1,3 +1,18 @@ +/* + * 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.extra.npm; public interface NpmTest { diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/prettier/PrettierFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java similarity index 92% rename from lib-extra/src/test/java/com/diffplug/spotless/extra/npm/prettier/PrettierFormatterStepTest.java rename to lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java index 66c33f4bd8..def5bd3222 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/prettier/PrettierFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm.prettier; +package com.diffplug.spotless.extra.npm; import java.io.File; import java.io.IOException; @@ -28,9 +28,6 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.LineEnding; import com.diffplug.spotless.TestProvisioner; -import com.diffplug.spotless.extra.npm.NpmTest; -import com.diffplug.spotless.extra.npm.prettier.options.PrettierOptions; -import com.diffplug.spotless.extra.npm.prettier.options.PrettierParser; @Category(NpmTest.class) public class PrettierFormatterStepTest { diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java similarity index 94% rename from lib-extra/src/test/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtFormatterStepTest.java rename to lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java index 6f403f2695..6c4c4ecbdb 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/tsfmt/TsFmtFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm.tsfmt; +package com.diffplug.spotless.extra.npm; import java.io.File; import java.io.IOException; @@ -24,7 +24,6 @@ import org.junit.experimental.categories.Category; import com.diffplug.spotless.*; -import com.diffplug.spotless.extra.npm.NpmTest; @Category(NpmTest.class) public class TsFmtFormatterStepTest { From 37fff43ed9df6009ddc854287db3e6e63582894d Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:45:25 +0200 Subject: [PATCH 06/45] restrict visibility --- .../extra/npm/NpmFormatterStepStateBase.java | 12 ------ .../extra/npm/PrettierFormatterStep.java | 1 - .../spotless/extra/npm/Reflective.java | 40 ++++++++----------- .../spotless/extra/npm/TsFmtResult.java | 10 ++--- 4 files changed, 21 insertions(+), 42 deletions(-) diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java index 4caeb1ca8e..a1b4202d9f 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java @@ -49,13 +49,6 @@ protected NpmFormatterStepStateBase(String stepName, Provisioner provisioner, Np this.nodeModulesDir = prepareNodeModules(buildDir, npm); this.nodeModulesSignature = FileSignature.signAsList(this.nodeModulesDir); - - /* - - - - - */ } private File prepareNodeModules(File buildDir, File npm) throws IOException { @@ -94,11 +87,6 @@ protected File nodeModulePath() { return new File(new File(this.nodeModulesDir, "node_modules"), this.npmConfig.getNpmModule()); } - private File j2V8JarFile() { - // return new File("/Users/simschla/Downloads", "j2v8_macos_x86_64-nodejs-8.2.1-SNAPSHOT.jar"); // TODO (simschla, 27.07.18): adapt - return new File("/Users/simschla/Downloads", "j2v8_macosx_x86_64-4.6.0.jar"); // TODO (simschla, 27.07.18): adapt - } - private String j2v8MavenCoordinate() { return "com.eclipsesource.j2v8:j2v8_" + arch() + ":4.6.0"; } diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java index bfdb0fbeaa..206000fc77 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java @@ -66,7 +66,6 @@ public FormatterFunc createFormatterFunc() { final NodeJSWrapper nodeJSWrapper = nodeJSWrapper(); final V8ObjectWrapper prettier = nodeJSWrapper.require(nodeModulePath()); - // TODO (simschla, 14.08.18): use prettier options final PrettierOptions[] resolvedPrettierOptions = new PrettierOptions[1]; if (this.prettierConfig.getPrettierConfigPath() != null) { final Exception[] toThrow = new Exception[1]; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java index c8c96b1dba..fa3320f8ad 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java @@ -22,18 +22,18 @@ import java.util.Objects; import java.util.StringJoiner; -public class Reflective { +class Reflective { private final ClassLoader classLoader; - public Reflective(ClassLoader classLoader) { + private Reflective(ClassLoader classLoader) { this.classLoader = requireNonNull(classLoader); } - public static Reflective withClassLoader(ClassLoader classLoader) { + static Reflective withClassLoader(ClassLoader classLoader) { return new Reflective(classLoader); } - public Class clazz(String className) { + Class clazz(String className) { try { return this.classLoader.loadClass(className); } catch (ClassNotFoundException e) { @@ -41,7 +41,7 @@ public Class clazz(String className) { } } - public Method staticMethod(String className, String methodName, Object... parameters) { + private Method staticMethod(String className, String methodName, Object... parameters) { try { final Class clazz = clazz(className); return clazz.getDeclaredMethod(methodName, types(parameters)); @@ -50,7 +50,7 @@ public Method staticMethod(String className, String methodName, Object... parame } } - public Object invokeStaticMethod(String className, String factoryMethodName, Object... parameters) { + Object invokeStaticMethod(String className, String factoryMethodName, Object... parameters) { try { Method m = staticMethod(className, factoryMethodName, parameters); return m.invoke(m.getDeclaringClass(), parameters); @@ -59,19 +59,19 @@ public Object invokeStaticMethod(String className, String factoryMethodName, Obj } } - public Class[] types(TypedValue[] typedValues) { + private Class[] types(TypedValue[] typedValues) { return Arrays.stream(typedValues) .map(TypedValue::getClazz) .toArray(Class[]::new); } - public Class[] types(Object[] arguments) { + Class[] types(Object[] arguments) { return Arrays.stream(arguments) .map(Object::getClass) .toArray(Class[]::new); } - public Object invokeMethod(Object target, String methodName, Object... parameters) { + Object invokeMethod(Object target, String methodName, Object... parameters) { Method m = method(target, clazz(target), methodName, parameters); try { return m.invoke(target, parameters); @@ -80,7 +80,7 @@ public Object invokeMethod(Object target, String methodName, Object... parameter } } - public Object invokeMethod(Object target, String methodName, TypedValue... parameters) { + Object invokeMethod(Object target, String methodName, TypedValue... parameters) { Method m = method(target, clazz(target), methodName, parameters); try { return m.invoke(target, objects(parameters)); @@ -155,7 +155,7 @@ private Class clazz(Object target) { return target.getClass(); } - public Object invokeConstructor(String className, TypedValue... parameters) { + Object invokeConstructor(String className, TypedValue... parameters) { try { final Constructor constructor = constructor(className, parameters); return constructor.newInstance(objects(parameters)); @@ -170,7 +170,7 @@ private Object[] objects(TypedValue[] parameters) { .toArray(); } - public Object invokeConstructor(String className, Object... parameters) { + Object invokeConstructor(String className, Object... parameters) { try { final Constructor constructor = constructor(className, parameters); return constructor.newInstance(parameters); @@ -199,19 +199,19 @@ private Constructor constructor(String className, Object[] parameters) { } } - public Object createDynamicProxy(InvocationHandler invocationHandler, String... interfaceNames) { + Object createDynamicProxy(InvocationHandler invocationHandler, String... interfaceNames) { Class[] clazzes = Arrays.stream(interfaceNames) .map(this::clazz) .toArray(Class[]::new); return Proxy.newProxyInstance(this.classLoader, clazzes, invocationHandler); } - public Object staticField(String className, String fieldName) { + Object staticField(String className, String fieldName) { final Class clazz = clazz(className); return staticField(clazz, fieldName); } - public Object staticField(Class clazz, String fieldName) { + private Object staticField(Class clazz, String fieldName) { try { return clazz.getDeclaredField(fieldName).get(clazz); } catch (IllegalAccessException | NoSuchFieldException e) { @@ -219,14 +219,10 @@ public Object staticField(Class clazz, String fieldName) { } } - public TypedValue typed(String className, Object obj) { + TypedValue typed(String className, Object obj) { return new TypedValue(clazz(className), obj); } - public static TypedValue typed(Class clazz, Object obj) { - return new TypedValue(clazz, obj); - } - public static class TypedValue { private final Class clazz; private final Object obj; @@ -270,10 +266,6 @@ public int hashCode() { } public static class ReflectiveException extends RuntimeException { - public ReflectiveException(String message) { - super(message); - } - public ReflectiveException(String message, Throwable cause) { super(message, cause); } diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtResult.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtResult.java index d64bdfec61..7ca8418a17 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtResult.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtResult.java @@ -15,27 +15,27 @@ */ package com.diffplug.spotless.extra.npm; -public class TsFmtResult { +class TsFmtResult { private final String message; private final Boolean error; private final String formatted; - public TsFmtResult(String message, Boolean error, String formatted) { + TsFmtResult(String message, Boolean error, String formatted) { this.message = message; this.error = error; this.formatted = formatted; } - public String getMessage() { + String getMessage() { return message; } - public Boolean isError() { + Boolean isError() { return error; } - public String getFormatted() { + String getFormatted() { return formatted; } } From ddfc882e2913b19d0a44e2284370fff110db0e1a Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:46:24 +0200 Subject: [PATCH 07/45] revert the from-file feature for JarState as it is not used right now --- .../main/java/com/diffplug/spotless/JarState.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/lib/src/main/java/com/diffplug/spotless/JarState.java b/lib/src/main/java/com/diffplug/spotless/JarState.java index 5fad56a56d..8d3506a2bb 100644 --- a/lib/src/main/java/com/diffplug/spotless/JarState.java +++ b/lib/src/main/java/com/diffplug/spotless/JarState.java @@ -73,18 +73,6 @@ public static JarState from(Collection mavenCoordinates, Provisioner pro return new JarState(mavenCoordinates, fileSignature, jars); } - public static JarState fromFiles(Set jars) throws IOException { - FileSignature fileSignature = FileSignature.signAsSet(jars); - Collection identifier = identifier(jars); - return new JarState(identifier, fileSignature, jars); - } - - private static Collection identifier(Set jars) { - return jars.stream() - .map(File::getName) - .collect(Collectors.toList()); - } - URL[] jarUrls() { return jars.stream().map(File::toURI).map(ThrowingEx.wrap(URI::toURL)).toArray(URL[]::new); } From ef4d24404e33fa3c209c0c7aeea104c4e4580efd Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:46:49 +0200 Subject: [PATCH 08/45] adapt to package renaming --- lib-extra/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib-extra/build.gradle b/lib-extra/build.gradle index e7876297bc..1a4b48ac61 100644 --- a/lib-extra/build.gradle +++ b/lib-extra/build.gradle @@ -24,6 +24,6 @@ dependencies { // we'll hold the core lib to a high standard spotbugs { reportLevel = 'low' } // low|medium|high (low = sensitive to even minor mistakes) -test { useJUnit { excludeCategories 'com.diffplug.spotless.extra.nodebased.NpmTest' } } +test { useJUnit { excludeCategories 'com.diffplug.spotless.extra.npm.NpmTest' } } -task npmTest(type: Test) { useJUnit { includeCategories 'com.diffplug.spotless.extra.nodebased.NpmTest' } } +task npmTest(type: Test) { useJUnit { includeCategories 'com.diffplug.spotless.extra.npm.NpmTest' } } From 4f169986c876d4ac919405686dc196769c62ae3c Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:47:15 +0200 Subject: [PATCH 09/45] using map as config api for npm formatter steps as discussed in PR #283 --- .../spotless/extra/npm/NodeJSWrapper.java | 8 + .../extra/npm/NpmFormatterStepStateBase.java | 12 +- .../spotless/extra/npm/PrettierConfig.java | 36 +- .../extra/npm/PrettierFormatterStep.java | 26 +- .../spotless/extra/npm/PrettierOptions.java | 331 ------------------ .../spotless/extra/npm/Reflective.java | 4 +- .../extra/npm/TsFmtFormatterStep.java | 28 +- .../spotless/extra/npm/TsFmtOptions.java | 236 ------------- .../extra/npm/V8ObjectUtilsWrapper.java | 35 ++ .../extra/npm/PrettierFormatterStepTest.java | 11 +- .../extra/npm/TsFmtFormatterStepTest.java | 7 +- 11 files changed, 128 insertions(+), 606 deletions(-) delete mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierOptions.java delete mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtOptions.java create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectUtilsWrapper.java diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NodeJSWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NodeJSWrapper.java index 605d0abdcc..ad76479eb2 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NodeJSWrapper.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NodeJSWrapper.java @@ -16,6 +16,7 @@ package com.diffplug.spotless.extra.npm; import java.io.File; +import java.util.Map; import java.util.Objects; public class NodeJSWrapper extends ReflectiveObjectWrapper { @@ -42,6 +43,13 @@ public V8ObjectWrapper createNewObject() { return objectWrapper; } + public V8ObjectWrapper createNewObject(Map 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) { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java index a1b4202d9f..e413120e8e 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java @@ -28,19 +28,23 @@ import com.diffplug.spotless.*; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + public abstract class NpmFormatterStepStateBase implements Serializable { private static final long serialVersionUID = -5849375492831208496L; - public final JarState jarState; + private final JarState jarState; - public final FileSignature nodeModulesSignature; + @SuppressWarnings("unused") + private final FileSignature nodeModulesSignature; + @SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED") public final transient File nodeModulesDir; - public final NpmConfig npmConfig; + private final NpmConfig npmConfig; - public final String stepName; + private final String stepName; protected NpmFormatterStepStateBase(String stepName, Provisioner provisioner, NpmConfig npmConfig, File buildDir, File npm) throws IOException { this.stepName = stepName; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierConfig.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierConfig.java index fdc195c902..6f7043b5de 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierConfig.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierConfig.java @@ -16,23 +16,43 @@ package com.diffplug.spotless.extra.npm; import java.io.File; +import java.io.IOException; +import java.io.Serializable; +import java.util.Map; +import java.util.TreeMap; -public class PrettierConfig { +import com.diffplug.spotless.FileSignature; +import com.diffplug.spotless.ThrowingEx; - private final File prettierConfigPath; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; - private final PrettierOptions options; +public class PrettierConfig implements Serializable { - public PrettierConfig(File prettierConfigPath, PrettierOptions options) { - this.prettierConfigPath = prettierConfigPath; - this.options = options == null ? PrettierOptions.allDefaults() : options; + private static final long serialVersionUID = -8709340269833126583L; + + @SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED") + private final transient File prettierConfigPath; + + @SuppressWarnings("unused") + private final FileSignature prettierConfigPathSignature; + + private final TreeMap options; + + public PrettierConfig(File prettierConfigPath, Map options) { + try { + this.prettierConfigPath = prettierConfigPath; + this.prettierConfigPathSignature = FileSignature.signAsList(this.prettierConfigPath); + this.options = options == null ? new TreeMap<>() : new TreeMap<>(options); + } catch (IOException e) { + throw ThrowingEx.asRuntime(e); + } } public File getPrettierConfigPath() { return prettierConfigPath; } - public PrettierOptions getOptions() { - return options; + public Map getOptions() { + return new TreeMap<>(this.options); } } diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java index 206000fc77..8b7d96c7df 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java @@ -21,6 +21,8 @@ import java.io.File; import java.io.IOException; import java.io.Serializable; +import java.util.Map; +import java.util.TreeMap; import javax.annotation.Nonnull; @@ -66,7 +68,8 @@ public FormatterFunc createFormatterFunc() { final NodeJSWrapper nodeJSWrapper = nodeJSWrapper(); final V8ObjectWrapper prettier = nodeJSWrapper.require(nodeModulePath()); - final PrettierOptions[] resolvedPrettierOptions = new PrettierOptions[1]; + @SuppressWarnings("unchecked") + final Map[] resolvedPrettierOptions = (Map[]) new Map[1]; if (this.prettierConfig.getPrettierConfigPath() != null) { final Exception[] toThrow = new Exception[1]; try ( @@ -76,9 +79,12 @@ public FormatterFunc createFormatterFunc() { if (configOptions == null) { toThrow[0] = new IllegalArgumentException("Cannot find or read config file " + this.prettierConfig.getPrettierConfigPath()); } else { - resolvedPrettierOptions[0] = PrettierOptions - .fromV8Object(configOptions) - .overrideWith(this.prettierConfig.getOptions()); + Map resolvedOptions = new TreeMap<>(V8ObjectUtilsWrapper.toMap(configOptions)); + resolvedOptions.putAll(this.prettierConfig.getOptions()); + toThrow[0] = validateOptions(resolvedOptions); + if (toThrow[0] == null) { + resolvedPrettierOptions[0] = resolvedOptions; + } } } catch (Exception e) { toThrow[0] = e; @@ -107,10 +113,7 @@ public FormatterFunc createFormatterFunc() { resolvedPrettierOptions[0] = this.prettierConfig.getOptions(); } - // final V8ObjectWrapper prettierConfig = nodeJSWrapper.createNewObject() - // .add("parser", "typescript"); - - final V8ObjectWrapper prettierConfig = resolvedPrettierOptions[0].toV8Object(nodeJSWrapper); + final V8ObjectWrapper prettierConfig = nodeJSWrapper.createNewObject(resolvedPrettierOptions[0]); return FormatterFunc.Closeable.of(() -> { System.out.println("RELEASING PRETTIER FORMATTER FUNCTION"); @@ -126,5 +129,12 @@ public FormatterFunc createFormatterFunc() { } } + + private Exception validateOptions(Map resolvedOptions) { + if (resolvedOptions.containsKey("filePath")) { + return new RuntimeException("option 'filePath' is not supported.)"); + } + return null; + } } } diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierOptions.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierOptions.java deleted file mode 100644 index 6a8f2e2eaf..0000000000 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierOptions.java +++ /dev/null @@ -1,331 +0,0 @@ -/* - * 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.extra.npm; - -import java.util.Optional; - -public class PrettierOptions { - - private final Integer printWidth; - - private final Integer tabWidth; - - private final Boolean useTabs; - - private final Boolean semi; - - private final Boolean singleQuote; - - // "none", "es5" or "all" - private final String trailingComma; - - private final Boolean bracketSpacing; - - private final Boolean jsxBracketSameLine; - - // "avoid", "always" - private final String arrowParens; - - private final Integer rangeStart; - - private final Integer rangeEnd; - - private final PrettierParser parser; - - // not supported - // String filePath; - - private final Boolean requirePragma; - - private final Boolean insertPragma; - - // "always", "never", "preserve" - private final String proseWrap; - - private PrettierOptions(Builder builder) { - printWidth = builder.printWidth; - tabWidth = builder.tabWidth; - useTabs = builder.useTabs; - semi = builder.semi; - singleQuote = builder.singleQuote; - trailingComma = builder.trailingComma; - bracketSpacing = builder.bracketSpacing; - jsxBracketSameLine = builder.jsxBracketSameLine; - arrowParens = builder.arrowParens; - rangeStart = builder.rangeStart; - rangeEnd = builder.rangeEnd; - parser = builder.parser; - requirePragma = builder.requirePragma; - insertPragma = builder.insertPragma; - proseWrap = builder.proseWrap; - } - - public static Builder newBuilder() { - return new Builder(); - } - - public static Builder newBuilder(PrettierOptions copy) { - Builder builder = new Builder(); - builder.printWidth = copy.getPrintWidth(); - builder.tabWidth = copy.getTabWidth(); - builder.useTabs = copy.getUseTabs(); - builder.semi = copy.getSemi(); - builder.singleQuote = copy.getSingleQuote(); - builder.trailingComma = copy.getTrailingComma(); - builder.bracketSpacing = copy.getBracketSpacing(); - builder.jsxBracketSameLine = copy.getJsxBracketSameLine(); - builder.arrowParens = copy.getArrowParens(); - builder.rangeStart = copy.getRangeStart(); - builder.rangeEnd = copy.getRangeEnd(); - builder.parser = copy.getParser(); - builder.requirePragma = copy.getRequirePragma(); - builder.insertPragma = copy.getInsertPragma(); - builder.proseWrap = copy.getProseWrap(); - return builder; - } - - public static PrettierOptions allDefaults() { - return PrettierOptions.newBuilder().build(); - } - - public Integer getPrintWidth() { - return printWidth; - } - - public Integer getTabWidth() { - return tabWidth; - } - - public Boolean getUseTabs() { - return useTabs; - } - - public Boolean getSemi() { - return semi; - } - - public Boolean getSingleQuote() { - return singleQuote; - } - - public String getTrailingComma() { - return trailingComma; - } - - public Boolean getBracketSpacing() { - return bracketSpacing; - } - - public Boolean getJsxBracketSameLine() { - return jsxBracketSameLine; - } - - public String getArrowParens() { - return arrowParens; - } - - public Integer getRangeStart() { - return rangeStart; - } - - public Integer getRangeEnd() { - return rangeEnd; - } - - public PrettierParser getParser() { - return parser; - } - - public Boolean getRequirePragma() { - return requirePragma; - } - - public Boolean getInsertPragma() { - return insertPragma; - } - - public String getProseWrap() { - return proseWrap; - } - - public static PrettierOptions fromV8Object(V8ObjectWrapper v8PrettierOptions) { - if (v8PrettierOptions == null) { - return allDefaults(); - } - Builder builder = newBuilder(); - v8PrettierOptions.getOptionalInteger("printWidth").ifPresent(builder::withPrintWidth); - v8PrettierOptions.getOptionalInteger("tabWidth").ifPresent(builder::withTabWidth); - v8PrettierOptions.getOptionalBoolean("useTabs").ifPresent(builder::withUseTabs); - v8PrettierOptions.getOptionalBoolean("semi").ifPresent(builder::withSemi); - v8PrettierOptions.getOptionalBoolean("singleQuote").ifPresent(builder::withSingleQuote); - v8PrettierOptions.getOptionalString("trailingComma").ifPresent(builder::withTrailingComma); - v8PrettierOptions.getOptionalBoolean("bracketSpacing").ifPresent(builder::withBracketSpacing); - v8PrettierOptions.getOptionalBoolean("jsxBracketSameLine").ifPresent(builder::withJsxBracketSameLine); - v8PrettierOptions.getOptionalString("arrowParens").ifPresent(builder::withArrowParens); - v8PrettierOptions.getOptionalInteger("rangeStart").ifPresent(builder::withRangeStart); - v8PrettierOptions.getOptionalInteger("rangeEnd").ifPresent(builder::withRangeEnd); - v8PrettierOptions.getOptionalString("parser").map(PrettierParser::getByParserName).ifPresent(builder::withParser); - v8PrettierOptions.getOptionalBoolean("requirePragma").ifPresent(builder::withRequirePragma); - v8PrettierOptions.getOptionalBoolean("insertPragma").ifPresent(builder::withInsertPragma); - v8PrettierOptions.getOptionalString("proseWrap").ifPresent(builder::withProseWrap); - return builder.build(); - } - - public PrettierOptions overrideWith(PrettierOptions overrides) { - if (overrides == null) { - return this; - } - final Builder builder = newBuilder(this); - Optional.ofNullable(overrides.getPrintWidth()).ifPresent(builder::withPrintWidth); - Optional.ofNullable(overrides.getTabWidth()).ifPresent(builder::withTabWidth); - Optional.ofNullable(overrides.getUseTabs()).ifPresent(builder::withUseTabs); - Optional.ofNullable(overrides.getSemi()).ifPresent(builder::withSemi); - Optional.ofNullable(overrides.getSingleQuote()).ifPresent(builder::withSingleQuote); - Optional.ofNullable(overrides.getTrailingComma()).ifPresent(builder::withTrailingComma); - Optional.ofNullable(overrides.getBracketSpacing()).ifPresent(builder::withBracketSpacing); - Optional.ofNullable(overrides.getJsxBracketSameLine()).ifPresent(builder::withJsxBracketSameLine); - Optional.ofNullable(overrides.getArrowParens()).ifPresent(builder::withArrowParens); - Optional.ofNullable(overrides.getRangeStart()).ifPresent(builder::withRangeStart); - Optional.ofNullable(overrides.getRangeEnd()).ifPresent(builder::withRangeEnd); - Optional.ofNullable(overrides.getParser()).ifPresent(builder::withParser); - Optional.ofNullable(overrides.getRequirePragma()).ifPresent(builder::withRequirePragma); - Optional.ofNullable(overrides.getInsertPragma()).ifPresent(builder::withInsertPragma); - Optional.ofNullable(overrides.getProseWrap()).ifPresent(builder::withProseWrap); - return builder.build(); - } - - public V8ObjectWrapper toV8Object(NodeJSWrapper nodeJSWrapper) { - if (nodeJSWrapper == null) { - throw new IllegalArgumentException("cannot work without nodeJSWrapper"); - } - final V8ObjectWrapper v8Object = nodeJSWrapper.createNewObject(); - Optional.ofNullable(getPrintWidth()).ifPresent(val -> v8Object.add("printWidth", val)); - Optional.ofNullable(getTabWidth()).ifPresent(val -> v8Object.add("tabWidth", val)); - Optional.ofNullable(getUseTabs()).ifPresent(val -> v8Object.add("useTabs", val)); - Optional.ofNullable(getSemi()).ifPresent(val -> v8Object.add("semi", val)); - Optional.ofNullable(getSingleQuote()).ifPresent(val -> v8Object.add("singleQuote", val)); - Optional.ofNullable(getTrailingComma()).ifPresent(val -> v8Object.add("trailingComma", val)); - Optional.ofNullable(getBracketSpacing()).ifPresent(val -> v8Object.add("bracketSpacing", val)); - Optional.ofNullable(getJsxBracketSameLine()).ifPresent(val -> v8Object.add("jsxBracketSameLine", val)); - Optional.ofNullable(getArrowParens()).ifPresent(val -> v8Object.add("arrowParens", val)); - Optional.ofNullable(getRangeStart()).ifPresent(val -> v8Object.add("rangeStart", val)); - Optional.ofNullable(getRangeEnd()).ifPresent(val -> v8Object.add("rangeEnd", val)); - Optional.ofNullable(getParser()).map(PrettierParser::parserName).ifPresent(val -> v8Object.add("parser", val)); - Optional.ofNullable(getRequirePragma()).ifPresent(val -> v8Object.add("requirePragma", val)); - Optional.ofNullable(getInsertPragma()).ifPresent(val -> v8Object.add("insertPragma", val)); - Optional.ofNullable(getProseWrap()).ifPresent(val -> v8Object.add("proseWrap", val)); - return v8Object; - } - - public static final class Builder { - private Integer printWidth; - private Integer tabWidth; - private Boolean useTabs; - private Boolean semi; - private Boolean singleQuote; - private String trailingComma; - private Boolean bracketSpacing; - private Boolean jsxBracketSameLine; - private String arrowParens; - private Integer rangeStart; - private Integer rangeEnd; - private PrettierParser parser; - private Boolean requirePragma; - private Boolean insertPragma; - private String proseWrap; - - private Builder() {} - - public Builder withPrintWidth(Integer printWidth) { - this.printWidth = printWidth; - return this; - } - - public Builder withTabWidth(Integer tabWidth) { - this.tabWidth = tabWidth; - return this; - } - - public Builder withUseTabs(Boolean useTabs) { - this.useTabs = useTabs; - return this; - } - - public Builder withSemi(Boolean semi) { - this.semi = semi; - return this; - } - - public Builder withSingleQuote(Boolean singleQuote) { - this.singleQuote = singleQuote; - return this; - } - - public Builder withTrailingComma(String trailingComma) { - this.trailingComma = trailingComma; - return this; - } - - public Builder withBracketSpacing(Boolean bracketSpacing) { - this.bracketSpacing = bracketSpacing; - return this; - } - - public Builder withJsxBracketSameLine(Boolean jsxBracketSameLine) { - this.jsxBracketSameLine = jsxBracketSameLine; - return this; - } - - public Builder withArrowParens(String arrowParens) { - this.arrowParens = arrowParens; - return this; - } - - public Builder withRangeStart(Integer rangeStart) { - this.rangeStart = rangeStart; - return this; - } - - public Builder withRangeEnd(Integer rangeEnd) { - this.rangeEnd = rangeEnd; - return this; - } - - public Builder withParser(PrettierParser parser) { - this.parser = parser; - return this; - } - - public Builder withRequirePragma(Boolean requirePragma) { - this.requirePragma = requirePragma; - return this; - } - - public Builder withInsertPragma(Boolean insertPragma) { - this.insertPragma = insertPragma; - return this; - } - - public Builder withProseWrap(String proseWrap) { - this.proseWrap = proseWrap; - return this; - } - - public PrettierOptions build() { - return new PrettierOptions(this); - } - } -} diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java index fa3320f8ad..7e56a10047 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java @@ -50,9 +50,9 @@ private Method staticMethod(String className, String methodName, Object... param } } - Object invokeStaticMethod(String className, String factoryMethodName, Object... parameters) { + Object invokeStaticMethod(String className, String methodName, Object... parameters) { try { - Method m = staticMethod(className, factoryMethodName, parameters); + Method m = staticMethod(className, methodName, parameters); return m.invoke(m.getDeclaringClass(), parameters); } catch (IllegalAccessException | InvocationTargetException e) { throw new ReflectiveException(e); diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java index 5161e6aa80..0bd5a96365 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java @@ -21,9 +21,11 @@ import java.io.File; import java.io.IOException; import java.io.Serializable; +import java.util.*; import javax.annotation.Nonnull; +import com.diffplug.common.collect.ImmutableList; import com.diffplug.spotless.FormatterFunc; import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.Provisioner; @@ -32,7 +34,7 @@ public class TsFmtFormatterStep { public static final String NAME = "tsfmt-format"; - public static FormatterStep create(Provisioner provisioner, File buildDir, File npm, TsFmtOptions tsFmtOptions) { + public static FormatterStep create(Provisioner provisioner, File buildDir, File npm, Map tsFmtOptions) { requireNonNull(provisioner); requireNonNull(buildDir); requireNonNull(npm); @@ -46,9 +48,9 @@ public static class State extends NpmFormatterStepStateBase implements Serializa private static final long serialVersionUID = -3811104513825329168L; - private final TsFmtOptions tsFmtOptions; + private final TreeMap tsFmtOptions; - public State(String stepName, Provisioner provisioner, File buildDir, File npm, TsFmtOptions tsFmtOptions) throws IOException { + public State(String stepName, Provisioner provisioner, File buildDir, File npm, Map tsFmtOptions) throws IOException { super(stepName, provisioner, new NpmConfig( @@ -56,7 +58,7 @@ public State(String stepName, Provisioner provisioner, File buildDir, File npm, "typescript-formatter"), buildDir, npm); - this.tsFmtOptions = tsFmtOptions; + this.tsFmtOptions = tsFmtOptions == null ? new TreeMap<>() : new TreeMap<>(tsFmtOptions); } @Override @@ -65,8 +67,8 @@ public FormatterFunc createFormatterFunc() { final NodeJSWrapper nodeJSWrapper = nodeJSWrapper(); final V8ObjectWrapper tsFmt = nodeJSWrapper.require(nodeModulePath()); - - final V8ObjectWrapper tsfmtOptions = tsFmtOptions.toV8Object(nodeJSWrapper); + validateOptions(tsFmtOptions); + final V8ObjectWrapper formatterOptions = nodeJSWrapper.createNewObject(tsFmtOptions); final TsFmtResult[] tsFmtResult = new TsFmtResult[1]; V8FunctionWrapper formatResultCallback = nodeJSWrapper.createNewFunction((receiver, parameters) -> { @@ -88,19 +90,18 @@ public FormatterFunc createFormatterFunc() { return FormatterFunc.Closeable.of(() -> { // TODO (simschla, 09.08.18): maybe release node stuff? System.out.println("RELEASING FORMATTER FUNCTION"); - asList(formatResultCallback, tsfmtOptions, tsFmt, nodeJSWrapper).forEach(ReflectiveObjectWrapper::release); + asList(formatResultCallback, formatterOptions, tsFmt, nodeJSWrapper).forEach(ReflectiveObjectWrapper::release); }, input -> { tsFmtResult[0] = null; // function processString(fileName: string, content: string, opts: Options): Promise { try ( - V8ArrayWrapper processStringArgs = nodeJSWrapper.createNewArray("spotless-format-string.ts", input, tsfmtOptions); + V8ArrayWrapper processStringArgs = nodeJSWrapper.createNewArray("spotless-format-string.ts", input, formatterOptions); V8ObjectWrapper promise = tsFmt.executeObjectFunction("processString", processStringArgs); V8ArrayWrapper callbacks = nodeJSWrapper.createNewArray(formatResultCallback)) { promise.executeVoidFunction("then", callbacks); - // TODO (simschla, 14.08.18): handle promise resolving without success while (tsFmtResult[0] == null) { nodeJSWrapper.handleMessage(); @@ -122,5 +123,14 @@ public FormatterFunc createFormatterFunc() { }); } + + private void validateOptions(Map options) { + final Set optionNames = new TreeSet<>(options.keySet()); + optionNames.retainAll(Arrays.asList("dryRun", "replace", "verify")); + + if (!optionNames.isEmpty()) { + throw new RuntimeException("The following config options are specified but not supported by spotless: " + optionNames); + } + } } } diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtOptions.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtOptions.java deleted file mode 100644 index 7b74b2ad4f..0000000000 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtOptions.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * 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.extra.npm; - -import java.io.Serializable; -import java.util.Optional; - -public class TsFmtOptions implements Serializable { - - private final Boolean verbose; - - private final String basedir; - - private final Boolean tsconfig; - - private final String tsconfigFile; - - private final Boolean tslint; - - private final String tslintFile; - - private final Boolean editorconfig; - - private final Boolean vscode; - - private final String vscodeFile; - - private final Boolean tsfmt; - - private final String tsfmtFile; - - private TsFmtOptions(Builder builder) { - verbose = builder.verbose; - basedir = builder.basedir; - tsconfig = builder.tsconfig; - tsconfigFile = builder.tsconfigFile; - tslint = builder.tslint; - tslintFile = builder.tslintFile; - editorconfig = builder.editorconfig; - vscode = builder.vscode; - vscodeFile = builder.vscodeFile; - tsfmt = builder.tsfmt; - tsfmtFile = builder.tsfmtFile; - } - - public Boolean getVerbose() { - return verbose; - } - - public String getBasedir() { - return basedir; - } - - public Boolean getTsconfig() { - return tsconfig; - } - - public String getTsconfigFile() { - return tsconfigFile; - } - - public Boolean getTslint() { - return tslint; - } - - public String getTslintFile() { - return tslintFile; - } - - public Boolean getEditorconfig() { - return editorconfig; - } - - public Boolean getVscode() { - return vscode; - } - - public String getVscodeFile() { - return vscodeFile; - } - - public Boolean getTsfmt() { - return tsfmt; - } - - public String getTsfmtFile() { - return tsfmtFile; - } - - public V8ObjectWrapper toV8Object(NodeJSWrapper nodeJSWrapper) { - if (nodeJSWrapper == null) { - throw new IllegalArgumentException("cannot work without nodeJSWrapper"); - } - final V8ObjectWrapper v8Object = nodeJSWrapper.createNewObject() - .add("replace", false) - .add("verify", false); - Optional.ofNullable(getVerbose()).ifPresent(val -> v8Object.add("verbose", val)); - Optional.ofNullable(getBasedir()).ifPresent(val -> v8Object.add("basedir", val)); - Optional.ofNullable(getTsconfig()).ifPresent(val -> v8Object.add("tsconfig", val)); - Optional.ofNullable(getTsconfigFile()).ifPresent(val -> v8Object.add("tsconfigFile", val)); - Optional.ofNullable(getTslint()).ifPresent(val -> v8Object.add("tslint", val)); - Optional.ofNullable(getTslintFile()).ifPresent(val -> v8Object.add("tslintFile", val)); - Optional.ofNullable(getEditorconfig()).ifPresent(val -> v8Object.add("editorconfig", val)); - Optional.ofNullable(getVscode()).ifPresent(val -> v8Object.add("vscode", val)); - Optional.ofNullable(getVscodeFile()).ifPresent(val -> v8Object.add("vscodeFile", val)); - Optional.ofNullable(getTsfmt()).ifPresent(val -> v8Object.add("tsfmt", val)); - Optional.ofNullable(getTsfmtFile()).ifPresent(val -> v8Object.add("tsfmtFile", val)); - return v8Object; - } - - public static Builder newBuilder() { - return new Builder(); - } - - public static Builder newBuilder(TsFmtOptions copy) { - Builder builder = new Builder(); - builder.verbose = copy.getVerbose(); - builder.basedir = copy.getBasedir(); - builder.tsconfig = copy.getTsconfig(); - builder.tsconfigFile = copy.getTsconfigFile(); - builder.tslint = copy.getTslint(); - builder.tslintFile = copy.getTslintFile(); - builder.editorconfig = copy.getEditorconfig(); - builder.vscode = copy.getVscode(); - builder.vscodeFile = copy.getVscodeFile(); - builder.tsfmt = copy.getTsfmt(); - builder.tsfmtFile = copy.getTsfmtFile(); - return builder; - } - - public static final class Builder { - private Boolean verbose; - private String basedir; - private Boolean tsconfig = false; - private String tsconfigFile = null; - private Boolean tslint = false; - private String tslintFile = null; - private Boolean editorconfig = false; - private Boolean vscode = false; - private String vscodeFile = null; - private Boolean tsfmt = false; - private String tsfmtFile = null; - - private Builder() {} - - public Builder withVerbose(Boolean verbose) { - this.verbose = verbose; - return this; - } - - public Builder withBasedir(String basedir) { - this.basedir = basedir; - return this; - } - - public Builder withTsconfig(Boolean tsconfig) { - this.tsconfig = tsconfig; - return this; - } - - public Builder withTsconfigFile(String tsconfigFile) { - this.tsconfigFile = tsconfigFile; - return withTsconfig(tsconfigFile != null); - } - - public Builder withTslint(Boolean tslint) { - this.tslint = tslint; - return this; - } - - public Builder withTslintFile(String tslintFile) { - this.tslintFile = tslintFile; - return withTslint(tslintFile != null); - } - - public Builder withEditorconfig(Boolean editorconfig) { - this.editorconfig = editorconfig; - return this; - } - - public Builder withVscode(Boolean vscode) { - this.vscode = vscode; - return this; - } - - public Builder withVscodeFile(String vscodeFile) { - this.vscodeFile = vscodeFile; - return withVscode(vscodeFile != null); - } - - public Builder withTsfmt(Boolean tsfmt) { - this.tsfmt = tsfmt; - return this; - } - - public Builder withTsfmtFile(String tsfmtFile) { - this.tsfmtFile = tsfmtFile; - return withTsfmt(tsfmtFile != null); - } - - public TsFmtOptions build() { - return new TsFmtOptions(this); - } - } - - /* - dryRun?: Boolean; - verbose?: Boolean; x - baseDir?: string; - replace: Boolean; - verify: Boolean; - tsconfig: Boolean; - tsconfigFile: string | null; - tslint: Boolean; - tslintFile: string | null; - editorconfig: Boolean; - vscode: Boolean; - vscodeFile: string | null; - tsfmt: Boolean; - tsfmtFile: string | null; - */ - -} diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectUtilsWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectUtilsWrapper.java new file mode 100644 index 0000000000..373233fd47 --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectUtilsWrapper.java @@ -0,0 +1,35 @@ +/* + * 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.extra.npm; + +import static java.util.Objects.requireNonNull; + +import java.util.Map; + +public class V8ObjectUtilsWrapper { + + public static final String WRAPPED_CLASS = "com.eclipsesource.v8.utils.V8ObjectUtils"; + + public static Map toMap(final V8ObjectWrapper object) { + requireNonNull(object); + + final Reflective reflective = object.reflective(); + + @SuppressWarnings("unchecked") + final Map map = (Map) reflective.invokeStaticMethod(WRAPPED_CLASS, "toMap", object.wrappedObj()); + return map; + } +} diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java index def5bd3222..581c24879d 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java @@ -23,6 +23,7 @@ import org.junit.Test; import org.junit.experimental.categories.Category; +import com.diffplug.common.collect.ImmutableMap; import com.diffplug.spotless.FormatExceptionPolicy; import com.diffplug.spotless.Formatter; import com.diffplug.spotless.FormatterStep; @@ -39,8 +40,8 @@ public void testPrettierTypescript() throws IOException { new File("/Users/simschla/tmp/demo-main/"), new File("/Users/simschla/.nvm/versions/node/v8.11.2/bin/npm"), new PrettierConfig(new File("/Users/simschla/tmp/.prettierrc"), - PrettierOptions.newBuilder() - .withBracketSpacing(true) + ImmutableMap. builder() + .put("bracketSpacing", Boolean.TRUE) .build())); final Formatter formatter = Formatter.builder() @@ -61,9 +62,9 @@ public void testPrettierJson() throws IOException { new File("/Users/simschla/tmp/demo-main/"), new File("/Users/simschla/.nvm/versions/node/v8.11.2/bin/npm"), new PrettierConfig(new File("/Users/simschla/tmp/.prettierrc"), - PrettierOptions.newBuilder() - .withBracketSpacing(true) - .withParser(PrettierParser.JSON) + ImmutableMap. builder() + .put("bracketSpacing", Boolean.TRUE) + .put("parser", "json") .build())); final Formatter formatter = Formatter.builder() diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java index 6c4c4ecbdb..c4b0ebdc54 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java @@ -23,6 +23,7 @@ import org.junit.Test; import org.junit.experimental.categories.Category; +import com.diffplug.common.collect.ImmutableMap; import com.diffplug.spotless.*; @Category(NpmTest.class) @@ -34,9 +35,9 @@ public void testTsFmt() throws IOException { TestProvisioner.mavenCentral(), new File("/Users/simschla/tmp/demo-main/"), new File("/Users/simschla/.nvm/versions/node/v8.11.2/bin/npm"), - TsFmtOptions.newBuilder() - .withBasedir("/Users/simschla/tmp/demo-basedir") - .withTslint(true) + ImmutableMap. builder() + .put("basedir", "/Users/simschla/tmp/demo-basedir") + .put("tslint", Boolean.TRUE) .build()); final Formatter formatter = Formatter.builder() From 74dfaeef836fd87de097ee578fbdfa2fc8bd1ceb Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:47:33 +0200 Subject: [PATCH 10/45] clearing up resources after prettier/tsfmt run --- .../extra/npm/PrettierFormatterStep.java | 19 ++++++++------- .../extra/npm/TsFmtFormatterStep.java | 24 ++++++++++--------- .../extra/npm/PrettierFormatterStepTest.java | 14 ++++++----- .../extra/npm/TsFmtFormatterStepTest.java | 7 +++--- 4 files changed, 35 insertions(+), 29 deletions(-) diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java index 8b7d96c7df..fe9838fdeb 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java @@ -75,15 +75,16 @@ public FormatterFunc createFormatterFunc() { try ( V8FunctionWrapper resolveConfigCallback = nodeJSWrapper.createNewFunction((receiver, parameters) -> { try { - final V8ObjectWrapper configOptions = parameters.getObject(0); // why is this always null - if (configOptions == null) { - toThrow[0] = new IllegalArgumentException("Cannot find or read config file " + this.prettierConfig.getPrettierConfigPath()); - } else { - Map resolvedOptions = new TreeMap<>(V8ObjectUtilsWrapper.toMap(configOptions)); - resolvedOptions.putAll(this.prettierConfig.getOptions()); - toThrow[0] = validateOptions(resolvedOptions); - if (toThrow[0] == null) { - resolvedPrettierOptions[0] = resolvedOptions; + try (final V8ObjectWrapper configOptions = parameters.getObject(0)) { + if (configOptions == null) { + toThrow[0] = new IllegalArgumentException("Cannot find or read config file " + this.prettierConfig.getPrettierConfigPath()); + } else { + Map resolvedOptions = new TreeMap<>(V8ObjectUtilsWrapper.toMap(configOptions)); + resolvedOptions.putAll(this.prettierConfig.getOptions()); + toThrow[0] = validateOptions(resolvedOptions); + if (toThrow[0] == null) { + resolvedPrettierOptions[0] = resolvedOptions; + } } } } catch (Exception e) { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java index 0bd5a96365..ff9b241403 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java @@ -25,10 +25,10 @@ import javax.annotation.Nonnull; -import com.diffplug.common.collect.ImmutableList; import com.diffplug.spotless.FormatterFunc; import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.Provisioner; +import com.diffplug.spotless.ThrowingEx; public class TsFmtFormatterStep { @@ -71,10 +71,14 @@ public FormatterFunc createFormatterFunc() { final V8ObjectWrapper formatterOptions = nodeJSWrapper.createNewObject(tsFmtOptions); final TsFmtResult[] tsFmtResult = new TsFmtResult[1]; + final Exception[] toThrow = new Exception[1]; + V8FunctionWrapper formatResultCallback = nodeJSWrapper.createNewFunction((receiver, parameters) -> { - final V8ObjectWrapper result = parameters.getObject(0); - tsFmtResult[0] = new TsFmtResult(result.getString("message"), result.getBoolean("error"), result.getString("dest")); - //result.release(); // TODO (simschla, 09.08.18): verify if release needed? + try (final V8ObjectWrapper result = parameters.getObject(0)) { + tsFmtResult[0] = new TsFmtResult(result.getString("message"), result.getBoolean("error"), result.getString("dest")); + } catch (Exception e) { + toThrow[0] = e; + } return receiver; }); @@ -103,10 +107,14 @@ public FormatterFunc createFormatterFunc() { promise.executeVoidFunction("then", callbacks); - while (tsFmtResult[0] == null) { + while (tsFmtResult[0] == null && toThrow[0] == null) { nodeJSWrapper.handleMessage(); } + if (toThrow[0] != null) { + throw ThrowingEx.asRuntime(toThrow[0]); + } + if (tsFmtResult[0] == null) { throw new IllegalStateException("should never happen"); } @@ -115,12 +123,6 @@ public FormatterFunc createFormatterFunc() { } return tsFmtResult[0].getFormatted(); } - - // TODO (simschla, 09.08.18): release - // callbacks.release(); - // args.release(); - // promise.release(); - }); } diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java index 581c24879d..e62eb1aa58 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java @@ -44,15 +44,16 @@ ImmutableMap. builder() .put("bracketSpacing", Boolean.TRUE) .build())); - final Formatter formatter = Formatter.builder() + try (final Formatter formatter = Formatter.builder() .encoding(StandardCharsets.UTF_8) .rootDir(new File("/Users/simschla/tmp/demo-basedir").toPath()) .lineEndingsPolicy(LineEnding.UNIX.createPolicy()) .steps(Arrays.asList(formatterStep)) .exceptionPolicy(FormatExceptionPolicy.failOnlyOnError()) - .build(); + .build()) { - System.out.println("formatted: " + formatter.applyToAndReturnResultIfDirty(new File("/Users/simschla/tmp/demo-basedir", "example.ts"))); + System.out.println("formatted: " + formatter.applyToAndReturnResultIfDirty(new File("/Users/simschla/tmp/demo-basedir", "example.ts"))); + } } @Test @@ -67,15 +68,16 @@ ImmutableMap. builder() .put("parser", "json") .build())); - final Formatter formatter = Formatter.builder() + try (final Formatter formatter = Formatter.builder() .encoding(StandardCharsets.UTF_8) .rootDir(new File("/Users/simschla/tmp/demo-basedir").toPath()) .lineEndingsPolicy(LineEnding.UNIX.createPolicy()) .steps(Arrays.asList(formatterStep)) .exceptionPolicy(FormatExceptionPolicy.failOnlyOnError()) - .build(); + .build()) { - System.out.println("formatted: " + formatter.applyToAndReturnResultIfDirty(new File("/Users/simschla/tmp/demo-basedir", "toformat.json"))); + System.out.println("formatted: " + formatter.applyToAndReturnResultIfDirty(new File("/Users/simschla/tmp/demo-basedir", "toformat.json"))); + } } } diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java index c4b0ebdc54..4d04bc4075 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java @@ -40,14 +40,15 @@ ImmutableMap. builder() .put("tslint", Boolean.TRUE) .build()); - final Formatter formatter = Formatter.builder() + try (final Formatter formatter = Formatter.builder() .encoding(StandardCharsets.UTF_8) .rootDir(new File("/Users/simschla/tmp/demo-basedir").toPath()) .lineEndingsPolicy(LineEnding.UNIX.createPolicy()) .steps(Arrays.asList(formatterStep)) .exceptionPolicy(FormatExceptionPolicy.failOnlyOnError()) - .build(); + .build()) { - System.out.println("formatted: " + formatter.applyToAndReturnResultIfDirty(new File("/Users/simschla/tmp/demo-basedir", "example.ts"))); + System.out.println("formatted: " + formatter.applyToAndReturnResultIfDirty(new File("/Users/simschla/tmp/demo-basedir", "example.ts"))); + } } } From e706531be5e28fcbb477ee746a70872afe78b923 Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:47:53 +0200 Subject: [PATCH 11/45] spotbugs cleanup --- .../spotless/extra/npm/PrettierParser.java | 34 ------------------- .../spotless/extra/npm/Reflective.java | 4 +-- 2 files changed, 2 insertions(+), 36 deletions(-) delete mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierParser.java diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierParser.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierParser.java deleted file mode 100644 index daf1dd8f98..0000000000 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierParser.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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.extra.npm; - -import java.util.Arrays; - -public enum PrettierParser { - - BABYLON, FLOW, TYPESCRIPT, POSTCSS, JSON, GRAPHQL, MARKDOWN; - - public static PrettierParser getByParserName(String parserName) { - return Arrays.stream(PrettierParser.values()) - .filter(parser -> parser.parserName().equals(parserName)) - .findFirst() - .orElseThrow(() -> new IllegalArgumentException("Unknown parser " + parserName)); - } - - public String parserName() { - return name().toLowerCase(); - } -} diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java index 7e56a10047..55ccfc1905 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java @@ -99,7 +99,7 @@ private Method method(Object target, Class clazz, String methodName, Object[] } else { // try with primitives - throw new ReflectiveException("Could not find method " + methodName + " with parameters " + parameters + " on object " + target, e); + throw new ReflectiveException("Could not find method " + methodName + " with parameters " + Arrays.toString(parameters) + " on object " + target, e); } } } @@ -114,7 +114,7 @@ private Method method(Object target, Class clazz, String methodName, TypedVal } else { // try with primitives - throw new ReflectiveException("Could not find method " + methodName + " with parameters " + parameters + " on object " + target, e); + throw new ReflectiveException("Could not find method " + methodName + " with parameters " + Arrays.toString(parameters) + " on object " + target, e); } } } From b8fb907e1567fd276cc4825c22a15a14c6ab9ce0 Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:48:09 +0200 Subject: [PATCH 12/45] cleanup autorelease-code --- .../diffplug/spotless/extra/npm/PrettierFormatterStep.java | 1 - .../com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java index fe9838fdeb..cf3f288373 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java @@ -117,7 +117,6 @@ public FormatterFunc createFormatterFunc() { final V8ObjectWrapper prettierConfig = nodeJSWrapper.createNewObject(resolvedPrettierOptions[0]); return FormatterFunc.Closeable.of(() -> { - System.out.println("RELEASING PRETTIER FORMATTER FUNCTION"); asList(prettierConfig, prettier, nodeJSWrapper).forEach(ReflectiveObjectWrapper::release); }, input -> { try (V8ArrayWrapper formatParams = nodeJSWrapper.createNewArray(input, prettierConfig)) { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java index ff9b241403..48e141cd27 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java @@ -92,8 +92,6 @@ public FormatterFunc createFormatterFunc() { } */ return FormatterFunc.Closeable.of(() -> { - // TODO (simschla, 09.08.18): maybe release node stuff? - System.out.println("RELEASING FORMATTER FUNCTION"); asList(formatResultCallback, formatterOptions, tsFmt, nodeJSWrapper).forEach(ReflectiveObjectWrapper::release); }, input -> { tsFmtResult[0] = null; @@ -128,7 +126,7 @@ public FormatterFunc createFormatterFunc() { private void validateOptions(Map options) { final Set optionNames = new TreeSet<>(options.keySet()); - optionNames.retainAll(Arrays.asList("dryRun", "replace", "verify")); + optionNames.retainAll(asList("dryRun", "replace", "verify")); if (!optionNames.isEmpty()) { throw new RuntimeException("The following config options are specified but not supported by spotless: " + optionNames); From 11b32f407e03b5e3b45dc1fcc550a216fa03e078 Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:48:29 +0200 Subject: [PATCH 13/45] restrict engine versions according to the npm packages used --- .../spotless/extra/npm/prettier-package.json | 19 +++++++++---------- .../spotless/extra/npm/tsfmt-package.json | 3 +-- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/prettier-package.json b/lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/prettier-package.json index 94de29a49e..160c71bc3d 100644 --- a/lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/prettier-package.json +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/prettier-package.json @@ -1,12 +1,11 @@ { - "name": "spotless-prettier-formatter-step", - "version": "1.0.0", - "devDependencies": { - "prettier": "1.13.4" - }, - "dependencies": {}, - "engines": { - "node": "8.11.2", - "npm": "5.6.0" - } + "name": "spotless-prettier-formatter-step", + "version": "1.0.0", + "devDependencies": { + "prettier": "1.13.4" + }, + "dependencies": {}, + "engines": { + "node": ">=6" + } } diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/tsfmt-package.json b/lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/tsfmt-package.json index 70705e2358..139ee30820 100644 --- a/lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/tsfmt-package.json +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/tsfmt-package.json @@ -8,7 +8,6 @@ }, "dependencies": {}, "engines": { - "node": "8.11.2", - "npm": "5.6.0" + "node": ">= 4.2.0" } } From c02b3ef33ff478de4a81a6e0868f4d7a36a86f8a Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:48:45 +0200 Subject: [PATCH 14/45] dynamically select j2v8 lib based on platform --- .../extra/npm/NpmFormatterStepStateBase.java | 7 +-- .../spotless/extra/npm/PlatformInfo.java | 50 +++++++++++++++++++ 2 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PlatformInfo.java diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java index e413120e8e..37b9bb27cd 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java @@ -92,12 +92,7 @@ protected File nodeModulePath() { } private String j2v8MavenCoordinate() { - return "com.eclipsesource.j2v8:j2v8_" + arch() + ":4.6.0"; - } - - private String arch() { - // TODO (simschla, 10.08.18): implement - return "macosx_x86_64"; + return "com.eclipsesource.j2v8:j2v8_" + PlatformInfo.normalizedOSName() + "_" + PlatformInfo.archName() + ":4.6.0"; } protected static String readFileFromClasspath(Class clazz, String name) { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PlatformInfo.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PlatformInfo.java new file mode 100644 index 0000000000..418d0ffc7a --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PlatformInfo.java @@ -0,0 +1,50 @@ +/* + * 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.extra.npm; + +import java.util.Locale; +import java.util.Optional; + +import com.diffplug.common.base.StandardSystemProperty; + +class PlatformInfo { + private PlatformInfo() { + // no instance + } + + static String normalizedOSName() { + final String osNameProperty = StandardSystemProperty.OS_NAME.value(); + if (osNameProperty == null) { + throw new RuntimeException("No info about OS available, cannot decide which implementation of j2v8 to use"); + } + final String normalizedOsName = osNameProperty.toLowerCase(Locale.ENGLISH); + if (normalizedOsName.contains("win")) { + return "win32"; + } + if (normalizedOsName.contains("mac")) { + return "macosx"; + } + if (normalizedOsName.contains("nix") || normalizedOsName.contains("nux") || normalizedOsName.contains("aix")) { + return "linux"; + } + throw new RuntimeException("Cannot handle os " + osNameProperty); + } + + static String archName() { + return Optional.ofNullable(StandardSystemProperty.OS_ARCH.value()) + .orElseThrow(() -> new RuntimeException("Arch not detectable.")); + } +} From 27dc6f911cb04310223b146c7e886c30beaa3f4d Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:49:37 +0200 Subject: [PATCH 15/45] add support for closing FormatterFunc --- .../com/diffplug/spotless/StepHarness.java | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/testlib/src/main/java/com/diffplug/spotless/StepHarness.java b/testlib/src/main/java/com/diffplug/spotless/StepHarness.java index 096b7ec1b3..fef037496d 100644 --- a/testlib/src/main/java/com/diffplug/spotless/StepHarness.java +++ b/testlib/src/main/java/com/diffplug/spotless/StepHarness.java @@ -24,7 +24,7 @@ import org.junit.Assert; /** An api for adding test cases. */ -public class StepHarness { +public class StepHarness implements AutoCloseable { private final FormatterFunc formatter; /** Creates a StepHarness around the given FormatterFunc. */ @@ -37,12 +37,20 @@ public static StepHarness forStep(FormatterStep step) { // We don't care if an individual FormatterStep is misbehaving on line-endings, because // Formatter fixes that. No reason to care in tests either. It's likely to pop up when // running tests on Windows from time-to-time - return new StepHarness(input -> LineEnding.toUnix(step.format(input, new File("")))); + return new StepHarness(FormatterFunc.Closeable.of( + () -> { + if (step instanceof FormatterStepImpl.Standard) { + ((FormatterStepImpl.Standard) step).cleanupFormatterFunc(); + } + }, + input -> LineEnding.toUnix(step.format(input, new File(""))))); } /** Creates a harness for testing a formatter whose steps don't depend on the file. */ public static StepHarness forFormatter(Formatter formatter) { - return new StepHarness(input -> formatter.compute(input, new File(""))); + return new StepHarness(FormatterFunc.Closeable.of( + formatter::close, + input -> formatter.compute(input, new File("")))); } /** Asserts that the given element is transformed as expected, and that the result is idempotent. */ @@ -84,4 +92,11 @@ public StepHarness testException(String resourceBefore, Consumer Date: Fri, 7 Sep 2018 08:49:58 +0200 Subject: [PATCH 16/45] implement behavioral tests --- .../npm/NpmFormatterStepCommonTests.java | 38 +++++++++ .../extra/npm/TsFmtFormatterStepTest.java | 22 ++++- .../resources/npm/tsfmt/tslint/tslint.clean | 6 ++ .../resources/npm/tsfmt/tslint/tslint.dirty | 6 ++ .../resources/npm/tsfmt/tslint/tslint.json | 83 +++++++++++++++++++ .../diffplug/spotless/ResourceHarness.java | 9 ++ 6 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmFormatterStepCommonTests.java create mode 100644 lib-extra/src/test/resources/npm/tsfmt/tslint/tslint.clean create mode 100644 lib-extra/src/test/resources/npm/tsfmt/tslint/tslint.dirty create mode 100644 lib-extra/src/test/resources/npm/tsfmt/tslint/tslint.json diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmFormatterStepCommonTests.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmFormatterStepCommonTests.java new file mode 100644 index 0000000000..0be3bc7ec4 --- /dev/null +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmFormatterStepCommonTests.java @@ -0,0 +1,38 @@ +/* + * 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.extra.npm; + +import java.io.File; +import java.io.IOException; + +import com.diffplug.spotless.ResourceHarness; + +public abstract class NpmFormatterStepCommonTests extends ResourceHarness { + + protected File npmExecutable() { + // TODO (simschla, 24.08.18): read from System.property or the like? + return new File("/Users/simschla/.nvm/versions/node/v8.11.2/bin/npm"); + } + + private File buildDir = null; + + protected File buildDir() throws IOException { + if (this.buildDir == null) { + this.buildDir = newFolder("build-dir"); + } + return this.buildDir; + } +} diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java index 4d04bc4075..617fed9f8b 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java @@ -27,7 +27,27 @@ import com.diffplug.spotless.*; @Category(NpmTest.class) -public class TsFmtFormatterStepTest { +public class TsFmtFormatterStepTest extends NpmFormatterStepCommonTests { + + @Test + public void formattingUsingTslint() throws Exception { + String filedir = "npm/tsfmt/tslint/"; + + File tsLintDir = createTestFile(filedir + "tslint.json").getParentFile(); + + final FormatterStep formatterStep = TsFmtFormatterStep.create( + TestProvisioner.mavenCentral(), + buildDir(), + npmExecutable(), + ImmutableMap. builder() + .put("basedir", tsLintDir.getPath()) + .put("tslint", Boolean.TRUE) + .build()); + + try (StepHarness stepHarness = StepHarness.forStep(formatterStep)) { + stepHarness.testResource(filedir + "tslint.dirty", filedir + "tslint.clean"); + } + } @Test public void testTsFmt() throws IOException { diff --git a/lib-extra/src/test/resources/npm/tsfmt/tslint/tslint.clean b/lib-extra/src/test/resources/npm/tsfmt/tslint/tslint.clean new file mode 100644 index 0000000000..48296fcf7e --- /dev/null +++ b/lib-extra/src/test/resources/npm/tsfmt/tslint/tslint.clean @@ -0,0 +1,6 @@ +class Sample { + hello(word: string = "world"): string { return "Hello, " + word; } +} + +var s: Sample = new Sample(); +if (s === s) { console.log(s.hello()); } diff --git a/lib-extra/src/test/resources/npm/tsfmt/tslint/tslint.dirty b/lib-extra/src/test/resources/npm/tsfmt/tslint/tslint.dirty new file mode 100644 index 0000000000..8ee345f189 --- /dev/null +++ b/lib-extra/src/test/resources/npm/tsfmt/tslint/tslint.dirty @@ -0,0 +1,6 @@ +class Sample { +hello(word:string="world"):string{return "Hello, " + word;} +} + +var s:Sample=new Sample(); +if(s===s){console.log(s.hello());} diff --git a/lib-extra/src/test/resources/npm/tsfmt/tslint/tslint.json b/lib-extra/src/test/resources/npm/tsfmt/tslint/tslint.json new file mode 100644 index 0000000000..4688d5f1e6 --- /dev/null +++ b/lib-extra/src/test/resources/npm/tsfmt/tslint/tslint.json @@ -0,0 +1,83 @@ +{ + "rules": { + "ban": [true, + ["_", "extend"], + ["_", "isNull"], + ["_", "isDefined"] + ], + "class-name": true, + "comment-format": [true, + "check-space", + "check-lowercase" + ], + "curly": true, + "eofline": true, + "forin": true, + "indent": [true, 4], + "interface-name": true, + "jsdoc-format": true, + "label-position": true, + "label-undefined": true, + "max-line-length": [true, 140], + "no-arg": true, + "no-bitwise": true, + "no-console": [true, + "debug", + "info", + "time", + "timeEnd", + "trace" + ], + "no-construct": true, + "no-debugger": true, + "no-duplicate-key": true, + "no-duplicate-variable": true, + "no-empty": true, + "no-eval": true, + "no-string-literal": true, + "trailing-comma": [true, { + "singleline": "never", + "multiline": "always" + }], + "no-trailing-whitespace": true, + "no-unused-expression": true, + "no-unused-variable": true, + "no-unreachable": true, + "no-use-before-declare": true, + "one-line": [true, + "check-open-brace", + "check-catch", + "check-else", + "check-whitespace" + ], + "quotemark": [true, "double"], + "radix": true, + "semicolon": true, + "triple-equals": [true, "allow-null-check"], + "typedef": [true, + "callSignature", + "catchClause", + "indexSignature", + "parameter", + "propertySignature", + "variableDeclarator" + ], + "typedef-whitespace": [true, + ["callSignature", "noSpace"], + ["catchClause", "noSpace"], + ["indexSignature", "space"] + ], + "use-strict": [true, + "check-module", + "check-function" + ], + "variable-name": false, + "whitespace": [true, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ] + } +} diff --git a/testlib/src/main/java/com/diffplug/spotless/ResourceHarness.java b/testlib/src/main/java/com/diffplug/spotless/ResourceHarness.java index 9d90b24a59..a119ea3608 100644 --- a/testlib/src/main/java/com/diffplug/spotless/ResourceHarness.java +++ b/testlib/src/main/java/com/diffplug/spotless/ResourceHarness.java @@ -86,6 +86,15 @@ protected File newFile(String subpath) throws IOException { return new File(rootFolder(), subpath); } + /** Creates and returns a new child-folder of the root folder. */ + protected File newFolder(String subpath) throws IOException { + File targetDir = newFile(subpath); + if (!targetDir.mkdir()) { + throw new IOException("Failed to create " + targetDir); + } + return targetDir; + } + protected String read(String path) throws IOException { return read(newFile(path).toPath(), StandardCharsets.UTF_8); } From 4b25b7cbeb9c064f40e5c9f45d41c5b7faf4acac Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:50:22 +0200 Subject: [PATCH 17/45] validate working config options for tsfmt - check various functioning config-file formats - check blacklisted config options are rejected --- .../extra/npm/BlacklistedOptionException.java | 23 ++++ .../extra/npm/TsFmtFormatterStep.java | 22 ++-- .../extra/npm/TsFmtFormatterStepTest.java | 102 +++++++++++------- .../npm/tsfmt/tsconfig/tsconfig.clean | 6 ++ .../npm/tsfmt/tsconfig/tsconfig.dirty | 6 ++ .../npm/tsfmt/tsconfig/tsconfig.json | 4 + .../resources/npm/tsfmt/tsfmt/tsfmt.clean | 5 + .../resources/npm/tsfmt/tsfmt/tsfmt.dirty | 5 + .../test/resources/npm/tsfmt/tsfmt/tsfmt.json | 4 + .../resources/npm/tsfmt/vscode/vscode.clean | 7 ++ .../resources/npm/tsfmt/vscode/vscode.dirty | 6 ++ .../resources/npm/tsfmt/vscode/vscode.json | 19 ++++ 12 files changed, 162 insertions(+), 47 deletions(-) create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/npm/BlacklistedOptionException.java create mode 100644 lib-extra/src/test/resources/npm/tsfmt/tsconfig/tsconfig.clean create mode 100644 lib-extra/src/test/resources/npm/tsfmt/tsconfig/tsconfig.dirty create mode 100644 lib-extra/src/test/resources/npm/tsfmt/tsconfig/tsconfig.json create mode 100644 lib-extra/src/test/resources/npm/tsfmt/tsfmt/tsfmt.clean create mode 100644 lib-extra/src/test/resources/npm/tsfmt/tsfmt/tsfmt.dirty create mode 100644 lib-extra/src/test/resources/npm/tsfmt/tsfmt/tsfmt.json create mode 100644 lib-extra/src/test/resources/npm/tsfmt/vscode/vscode.clean create mode 100644 lib-extra/src/test/resources/npm/tsfmt/vscode/vscode.dirty create mode 100644 lib-extra/src/test/resources/npm/tsfmt/vscode/vscode.json diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/BlacklistedOptionException.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/BlacklistedOptionException.java new file mode 100644 index 0000000000..83326cd9e0 --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/BlacklistedOptionException.java @@ -0,0 +1,23 @@ +/* + * 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.extra.npm; + +public class BlacklistedOptionException extends RuntimeException { + + public BlacklistedOptionException(String blacklistedOption) { + super("The config option '" + blacklistedOption + "' is not supported."); + } +} diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java index 48e141cd27..0f08b105a4 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java @@ -38,12 +38,21 @@ public static FormatterStep create(Provisioner provisioner, File buildDir, File requireNonNull(provisioner); requireNonNull(buildDir); requireNonNull(npm); - requireNonNull(tsFmtOptions); + validateOptions(requireNonNull(tsFmtOptions)); return FormatterStep.createLazy(NAME, () -> new State(NAME, provisioner, buildDir, npm, tsFmtOptions), State::createFormatterFunc); } + private static void validateOptions(Map options) { + final Set optionNames = new TreeSet<>(options.keySet()); + optionNames.retainAll(asList("dryRun", "replace", "verify")); + + if (!optionNames.isEmpty()) { + throw new BlacklistedOptionException("The following config options are specified but not supported by spotless: " + optionNames); + } + } + public static class State extends NpmFormatterStepStateBase implements Serializable { private static final long serialVersionUID = -3811104513825329168L; @@ -58,7 +67,7 @@ public State(String stepName, Provisioner provisioner, File buildDir, File npm, "typescript-formatter"), buildDir, npm); - this.tsFmtOptions = tsFmtOptions == null ? new TreeMap<>() : new TreeMap<>(tsFmtOptions); + this.tsFmtOptions = new TreeMap<>(tsFmtOptions); } @Override @@ -67,7 +76,6 @@ public FormatterFunc createFormatterFunc() { final NodeJSWrapper nodeJSWrapper = nodeJSWrapper(); final V8ObjectWrapper tsFmt = nodeJSWrapper.require(nodeModulePath()); - validateOptions(tsFmtOptions); final V8ObjectWrapper formatterOptions = nodeJSWrapper.createNewObject(tsFmtOptions); final TsFmtResult[] tsFmtResult = new TsFmtResult[1]; @@ -124,13 +132,5 @@ public FormatterFunc createFormatterFunc() { }); } - private void validateOptions(Map options) { - final Set optionNames = new TreeSet<>(options.keySet()); - optionNames.retainAll(asList("dryRun", "replace", "verify")); - - if (!optionNames.isEmpty()) { - throw new RuntimeException("The following config options are specified but not supported by spotless: " + optionNames); - } - } } } diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java index 617fed9f8b..121e0b4438 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java @@ -15,60 +15,90 @@ */ package com.diffplug.spotless.extra.npm; +import static org.assertj.core.api.Assertions.fail; + import java.io.File; -import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.Arrays; import org.junit.Test; import org.junit.experimental.categories.Category; +import org.junit.experimental.runners.Enclosed; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; import com.diffplug.common.collect.ImmutableMap; import com.diffplug.spotless.*; @Category(NpmTest.class) -public class TsFmtFormatterStepTest extends NpmFormatterStepCommonTests { +@RunWith(Enclosed.class) +public class TsFmtFormatterStepTest { + + @Category(NpmTest.class) + @RunWith(Parameterized.class) + public static class TsFmtUsingVariousFormattingFilesTest extends NpmFormatterStepCommonTests { + @Parameterized.Parameter + public String formattingConfigFile; + + @Parameterized.Parameters(name = "{index}: formatting using {0} is working") + public static Iterable formattingConfigFiles() { + return Arrays.asList("vscode/vscode.json", "tslint/tslint.json", "tsfmt/tsfmt.json", "tsconfig/tsconfig.json"); + } + + @Test + public void formattingUsingConfigFile() throws Exception { + String configFileName = formattingConfigFile.substring(formattingConfigFile.lastIndexOf('/') >= 0 ? formattingConfigFile.lastIndexOf('/') + 1 : 0); + String configFileNameWithoutExtension = configFileName.substring(0, configFileName.lastIndexOf('.')); + String filedir = "npm/tsfmt/" + configFileNameWithoutExtension + "/"; - @Test - public void formattingUsingTslint() throws Exception { - String filedir = "npm/tsfmt/tslint/"; + final File configFile = createTestFile(filedir + configFileName); + final String dirtyFile = filedir + configFileNameWithoutExtension + ".dirty"; + final String cleanFile = filedir + configFileNameWithoutExtension + ".clean"; - File tsLintDir = createTestFile(filedir + "tslint.json").getParentFile(); + // some config options expect to see at least one file in the baseDir, so let's write one there + Files.write(new File(configFile.getParentFile(), configFileNameWithoutExtension + ".ts").toPath(), getTestResource(dirtyFile).getBytes(StandardCharsets.UTF_8)); - final FormatterStep formatterStep = TsFmtFormatterStep.create( - TestProvisioner.mavenCentral(), - buildDir(), - npmExecutable(), - ImmutableMap. builder() - .put("basedir", tsLintDir.getPath()) - .put("tslint", Boolean.TRUE) - .build()); + final FormatterStep formatterStep = TsFmtFormatterStep.create( + TestProvisioner.mavenCentral(), + buildDir(), + npmExecutable(), + ImmutableMap. builder() + .put("basedir", configFile.getParent()) + .put(configFileNameWithoutExtension, Boolean.TRUE) + .put(configFileNameWithoutExtension + "File", configFile.getPath()) + .build()); - try (StepHarness stepHarness = StepHarness.forStep(formatterStep)) { - stepHarness.testResource(filedir + "tslint.dirty", filedir + "tslint.clean"); + try (StepHarness stepHarness = StepHarness.forStep(formatterStep)) { + stepHarness.testResource(dirtyFile, cleanFile); + } } } - @Test - public void testTsFmt() throws IOException { - final FormatterStep formatterStep = TsFmtFormatterStep.create( - TestProvisioner.mavenCentral(), - new File("/Users/simschla/tmp/demo-main/"), - new File("/Users/simschla/.nvm/versions/node/v8.11.2/bin/npm"), - ImmutableMap. builder() - .put("basedir", "/Users/simschla/tmp/demo-basedir") - .put("tslint", Boolean.TRUE) - .build()); - - try (final Formatter formatter = Formatter.builder() - .encoding(StandardCharsets.UTF_8) - .rootDir(new File("/Users/simschla/tmp/demo-basedir").toPath()) - .lineEndingsPolicy(LineEnding.UNIX.createPolicy()) - .steps(Arrays.asList(formatterStep)) - .exceptionPolicy(FormatExceptionPolicy.failOnlyOnError()) - .build()) { - - System.out.println("formatted: " + formatter.applyToAndReturnResultIfDirty(new File("/Users/simschla/tmp/demo-basedir", "example.ts"))); + @Category(NpmTest.class) + @RunWith(Parameterized.class) + public static class TsFmtBlacklistedOptionsTest extends NpmFormatterStepCommonTests { + @Parameterized.Parameter + public String blackListedOption; + + @Parameterized.Parameters(name = "{index}: config option '{0}' is blacklisted") + public static Iterable blacklistedOption() { + return Arrays.asList("dryRun", "replace", "verify"); } + + @Test(expected = BlacklistedOptionException.class) + public void blacklistedOptionIsThrown() throws Exception { + final FormatterStep formatterStep = TsFmtFormatterStep.create( + TestProvisioner.mavenCentral(), + buildDir(), + npmExecutable(), + ImmutableMap. builder() + .put(blackListedOption, Boolean.TRUE) + .build()); + + fail("should never be reached!"); + } + } + } diff --git a/lib-extra/src/test/resources/npm/tsfmt/tsconfig/tsconfig.clean b/lib-extra/src/test/resources/npm/tsfmt/tsconfig/tsconfig.clean new file mode 100644 index 0000000000..48296fcf7e --- /dev/null +++ b/lib-extra/src/test/resources/npm/tsfmt/tsconfig/tsconfig.clean @@ -0,0 +1,6 @@ +class Sample { + hello(word: string = "world"): string { return "Hello, " + word; } +} + +var s: Sample = new Sample(); +if (s === s) { console.log(s.hello()); } diff --git a/lib-extra/src/test/resources/npm/tsfmt/tsconfig/tsconfig.dirty b/lib-extra/src/test/resources/npm/tsfmt/tsconfig/tsconfig.dirty new file mode 100644 index 0000000000..8ee345f189 --- /dev/null +++ b/lib-extra/src/test/resources/npm/tsfmt/tsconfig/tsconfig.dirty @@ -0,0 +1,6 @@ +class Sample { +hello(word:string="world"):string{return "Hello, " + word;} +} + +var s:Sample=new Sample(); +if(s===s){console.log(s.hello());} diff --git a/lib-extra/src/test/resources/npm/tsfmt/tsconfig/tsconfig.json b/lib-extra/src/test/resources/npm/tsfmt/tsconfig/tsconfig.json new file mode 100644 index 0000000000..4b233e423e --- /dev/null +++ b/lib-extra/src/test/resources/npm/tsfmt/tsconfig/tsconfig.json @@ -0,0 +1,4 @@ +{ + // comment + /* comment */ +} diff --git a/lib-extra/src/test/resources/npm/tsfmt/tsfmt/tsfmt.clean b/lib-extra/src/test/resources/npm/tsfmt/tsfmt/tsfmt.clean new file mode 100644 index 0000000000..822424e9c3 --- /dev/null +++ b/lib-extra/src/test/resources/npm/tsfmt/tsfmt/tsfmt.clean @@ -0,0 +1,5 @@ +class Sample { + hello(word = "world") { return "Hello, " + word; } +} + +var s = new Sample(); diff --git a/lib-extra/src/test/resources/npm/tsfmt/tsfmt/tsfmt.dirty b/lib-extra/src/test/resources/npm/tsfmt/tsfmt/tsfmt.dirty new file mode 100644 index 0000000000..e2329f4f00 --- /dev/null +++ b/lib-extra/src/test/resources/npm/tsfmt/tsfmt/tsfmt.dirty @@ -0,0 +1,5 @@ +class Sample { +hello(word="world"){return "Hello, " + word;} +} + +var s=new Sample(); diff --git a/lib-extra/src/test/resources/npm/tsfmt/tsfmt/tsfmt.json b/lib-extra/src/test/resources/npm/tsfmt/tsfmt/tsfmt.json new file mode 100644 index 0000000000..52c343f843 --- /dev/null +++ b/lib-extra/src/test/resources/npm/tsfmt/tsfmt/tsfmt.json @@ -0,0 +1,4 @@ +{ + "indentSize": 1, + "convertTabsToSpaces": true +} diff --git a/lib-extra/src/test/resources/npm/tsfmt/vscode/vscode.clean b/lib-extra/src/test/resources/npm/tsfmt/vscode/vscode.clean new file mode 100644 index 0000000000..50cc165af1 --- /dev/null +++ b/lib-extra/src/test/resources/npm/tsfmt/vscode/vscode.clean @@ -0,0 +1,7 @@ +class Sample +{ + hello ( word: string = "world" ): string { return "Hello, " + word; } +} + +var s: Sample = new Sample(); +if ( s === s ) { console.log( s.hello() ); } diff --git a/lib-extra/src/test/resources/npm/tsfmt/vscode/vscode.dirty b/lib-extra/src/test/resources/npm/tsfmt/vscode/vscode.dirty new file mode 100644 index 0000000000..8ee345f189 --- /dev/null +++ b/lib-extra/src/test/resources/npm/tsfmt/vscode/vscode.dirty @@ -0,0 +1,6 @@ +class Sample { +hello(word:string="world"):string{return "Hello, " + word;} +} + +var s:Sample=new Sample(); +if(s===s){console.log(s.hello());} diff --git a/lib-extra/src/test/resources/npm/tsfmt/vscode/vscode.json b/lib-extra/src/test/resources/npm/tsfmt/vscode/vscode.json new file mode 100644 index 0000000000..b931d84a6d --- /dev/null +++ b/lib-extra/src/test/resources/npm/tsfmt/vscode/vscode.json @@ -0,0 +1,19 @@ +{ + // comment + "typescript.format.enable": true, + "typescript.format.insertSpaceAfterCommaDelimiter": true, + "typescript.format.insertSpaceAfterConstructor": true, + "typescript.format.insertSpaceAfterSemicolonInForStatements": true, + "typescript.format.insertSpaceBeforeAndAfterBinaryOperators": true, + "typescript.format.insertSpaceAfterKeywordsInControlFlowStatements": true, + "typescript.format.insertSpaceAfterFunctionKeywordForAnonymousFunctions": true, + "typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": true, + "typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": true, + "typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "typescript.format.insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": true, + "typescript.format.insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": true, + "typescript.format.insertSpaceAfterTypeAssertion": true, + "typescript.format.insertSpaceBeforeFunctionParenthesis": true, + "typescript.format.placeOpenBraceOnNewLineForFunctions": true, + "typescript.format.placeOpenBraceOnNewLineForControlBlocks": true +} From 48430c83731562afcf627e7c5ccaa0770de239ec Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:51:09 +0200 Subject: [PATCH 18/45] normalized arch name (matching arch for for ci) --- .../extra/npm/NpmFormatterStepStateBase.java | 2 +- .../spotless/extra/npm/PlatformInfo.java | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java index 37b9bb27cd..eb5c03aa07 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java @@ -92,7 +92,7 @@ protected File nodeModulePath() { } private String j2v8MavenCoordinate() { - return "com.eclipsesource.j2v8:j2v8_" + PlatformInfo.normalizedOSName() + "_" + PlatformInfo.archName() + ":4.6.0"; + return "com.eclipsesource.j2v8:j2v8_" + PlatformInfo.normalizedOSName() + "_" + PlatformInfo.normalizedArchName() + ":4.6.0"; } protected static String readFileFromClasspath(Class clazz, String name) { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PlatformInfo.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PlatformInfo.java index 418d0ffc7a..167bab6382 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PlatformInfo.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PlatformInfo.java @@ -16,7 +16,6 @@ package com.diffplug.spotless.extra.npm; import java.util.Locale; -import java.util.Optional; import com.diffplug.common.base.StandardSystemProperty; @@ -43,8 +42,19 @@ static String normalizedOSName() { throw new RuntimeException("Cannot handle os " + osNameProperty); } - static String archName() { - return Optional.ofNullable(StandardSystemProperty.OS_ARCH.value()) - .orElseThrow(() -> new RuntimeException("Arch not detectable.")); + static String normalizedArchName() { + final String osArchProperty = StandardSystemProperty.OS_ARCH.value(); + if (osArchProperty == null) { + throw new RuntimeException("No info about ARCH available, cannot decide which implementation of j2v8 to use"); + } + final String normalizedOsArch = osArchProperty.toLowerCase(Locale.ENGLISH); + + if (normalizedOsArch.contains("64")) { + return "x86_64"; + } + if (normalizedOsArch.contains("x86") || normalizedOsArch.contains("32")) { + return "x86"; + } + throw new RuntimeException("Cannot handle arch " + osArchProperty); } } From ff1d3d31b2b45715cc39f6a29af32c2361ac4ef5 Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:51:24 +0200 Subject: [PATCH 19/45] validate multiple formatting filetypes are working --- .../spotless/extra/npm/PrettierConfig.java | 2 +- .../extra/npm/PrettierFormatterStep.java | 11 +- .../extra/npm/PrettierFormatterStepTest.java | 102 +++++++++--------- .../prettier/filetypes/css/.prettierrc.yml | 1 + .../npm/prettier/filetypes/css/css.clean | 19 ++++ .../npm/prettier/filetypes/css/css.dirty | 20 ++++ .../filetypes/javascript-es5/.prettierrc.yml | 1 + .../javascript-es5/javascript-es5.clean | 43 ++++++++ .../javascript-es5/javascript-es5.dirty | 21 ++++ .../filetypes/javascript-es6/.prettierrc.yml | 1 + .../javascript-es6/javascript-es6.clean | 44 ++++++++ .../javascript-es6/javascript-es6.dirty | 21 ++++ .../prettier/filetypes/json/.prettierrc.yml | 1 + .../npm/prettier/filetypes/json/json.clean | 11 ++ .../npm/prettier/filetypes/json/json.dirty | 1 + .../filetypes/markdown/.prettierrc.yml | 1 + .../filetypes/markdown/markdown.clean | 21 ++++ .../filetypes/markdown/markdown.dirty | 20 ++++ .../prettier/filetypes/scss/.prettierrc.yml | 1 + .../npm/prettier/filetypes/scss/scss.clean | 35 ++++++ .../npm/prettier/filetypes/scss/scss.dirty | 34 ++++++ .../filetypes/typescript/.prettierrc.yml | 1 + .../filetypes/typescript/typescript.clean | 7 ++ .../filetypes/typescript/typescript.dirty | 5 + 24 files changed, 365 insertions(+), 59 deletions(-) create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/css/.prettierrc.yml create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/css/css.clean create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/css/css.dirty create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es5/.prettierrc.yml create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es5/javascript-es5.clean create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es5/javascript-es5.dirty create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es6/.prettierrc.yml create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es6/javascript-es6.clean create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es6/javascript-es6.dirty create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/json/.prettierrc.yml create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/json/json.clean create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/json/json.dirty create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/markdown/.prettierrc.yml create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/markdown/markdown.clean create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/markdown/markdown.dirty create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/scss/.prettierrc.yml create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/scss/scss.clean create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/scss/scss.dirty create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/typescript/.prettierrc.yml create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/typescript/typescript.clean create mode 100644 lib-extra/src/test/resources/npm/prettier/filetypes/typescript/typescript.dirty diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierConfig.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierConfig.java index 6f7043b5de..71e23306e1 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierConfig.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierConfig.java @@ -41,7 +41,7 @@ public class PrettierConfig implements Serializable { public PrettierConfig(File prettierConfigPath, Map options) { try { this.prettierConfigPath = prettierConfigPath; - this.prettierConfigPathSignature = FileSignature.signAsList(this.prettierConfigPath); + this.prettierConfigPathSignature = prettierConfigPath != null ? FileSignature.signAsList(this.prettierConfigPath) : FileSignature.signAsList(); this.options = options == null ? new TreeMap<>() : new TreeMap<>(options); } catch (IOException e) { throw ThrowingEx.asRuntime(e); diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java index cf3f288373..0327bda015 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java @@ -81,10 +81,7 @@ public FormatterFunc createFormatterFunc() { } else { Map resolvedOptions = new TreeMap<>(V8ObjectUtilsWrapper.toMap(configOptions)); resolvedOptions.putAll(this.prettierConfig.getOptions()); - toThrow[0] = validateOptions(resolvedOptions); - if (toThrow[0] == null) { - resolvedPrettierOptions[0] = resolvedOptions; - } + resolvedPrettierOptions[0] = resolvedOptions; } } } catch (Exception e) { @@ -130,11 +127,5 @@ public FormatterFunc createFormatterFunc() { } - private Exception validateOptions(Map resolvedOptions) { - if (resolvedOptions.containsKey("filePath")) { - return new RuntimeException("option 'filePath' is not supported.)"); - } - return null; - } } } diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java index e62eb1aa58..ad12c9511c 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java @@ -16,68 +16,74 @@ package com.diffplug.spotless.extra.npm; import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.util.Arrays; import org.junit.Test; import org.junit.experimental.categories.Category; +import org.junit.experimental.runners.Enclosed; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; import com.diffplug.common.collect.ImmutableMap; -import com.diffplug.spotless.FormatExceptionPolicy; -import com.diffplug.spotless.Formatter; -import com.diffplug.spotless.FormatterStep; -import com.diffplug.spotless.LineEnding; -import com.diffplug.spotless.TestProvisioner; +import com.diffplug.spotless.*; @Category(NpmTest.class) +@RunWith(Enclosed.class) public class PrettierFormatterStepTest { - @Test - public void testPrettierTypescript() throws IOException { - final FormatterStep formatterStep = PrettierFormatterStep.create( - TestProvisioner.mavenCentral(), - new File("/Users/simschla/tmp/demo-main/"), - new File("/Users/simschla/.nvm/versions/node/v8.11.2/bin/npm"), - new PrettierConfig(new File("/Users/simschla/tmp/.prettierrc"), - ImmutableMap. builder() - .put("bracketSpacing", Boolean.TRUE) - .build())); - - try (final Formatter formatter = Formatter.builder() - .encoding(StandardCharsets.UTF_8) - .rootDir(new File("/Users/simschla/tmp/demo-basedir").toPath()) - .lineEndingsPolicy(LineEnding.UNIX.createPolicy()) - .steps(Arrays.asList(formatterStep)) - .exceptionPolicy(FormatExceptionPolicy.failOnlyOnError()) - .build()) { - - System.out.println("formatted: " + formatter.applyToAndReturnResultIfDirty(new File("/Users/simschla/tmp/demo-basedir", "example.ts"))); + @Category(NpmTest.class) + @RunWith(Parameterized.class) + public static class PrettierFormattingOfFileTypesIsWorking extends NpmFormatterStepCommonTests { + + @Parameterized.Parameter + public String fileType; + + @Parameterized.Parameters(name = "{index}: prettier can be applied to {0}") + public static Iterable formattingConfigFiles() { + return Arrays.asList("typescript", "json", "javascript-es5", "javascript-es6", "css", "scss", "markdown"); + } + + @Test + public void formattingUsingConfigFile() throws Exception { + String filedir = "npm/prettier/filetypes/" + fileType + "/"; + + final File prettierRc = createTestFile(filedir + ".prettierrc.yml"); + final String dirtyFile = filedir + fileType + ".dirty"; + final String cleanFile = filedir + fileType + ".clean"; + + final FormatterStep formatterStep = PrettierFormatterStep.create( + TestProvisioner.mavenCentral(), + buildDir(), + npmExecutable(), + new PrettierConfig(prettierRc, null)); + + try (StepHarness stepHarness = StepHarness.forStep(formatterStep)) { + stepHarness.testResource(dirtyFile, cleanFile); + } } } - @Test - public void testPrettierJson() throws IOException { - final FormatterStep formatterStep = PrettierFormatterStep.create( - TestProvisioner.mavenCentral(), - new File("/Users/simschla/tmp/demo-main/"), - new File("/Users/simschla/.nvm/versions/node/v8.11.2/bin/npm"), - new PrettierConfig(new File("/Users/simschla/tmp/.prettierrc"), - ImmutableMap. builder() - .put("bracketSpacing", Boolean.TRUE) - .put("parser", "json") - .build())); - - try (final Formatter formatter = Formatter.builder() - .encoding(StandardCharsets.UTF_8) - .rootDir(new File("/Users/simschla/tmp/demo-basedir").toPath()) - .lineEndingsPolicy(LineEnding.UNIX.createPolicy()) - .steps(Arrays.asList(formatterStep)) - .exceptionPolicy(FormatExceptionPolicy.failOnlyOnError()) - .build()) { - - System.out.println("formatted: " + formatter.applyToAndReturnResultIfDirty(new File("/Users/simschla/tmp/demo-basedir", "toformat.json"))); + @Category(NpmTest.class) + public static class SpecificPrettierFormatterStepTests extends NpmFormatterStepCommonTests { + + @Test + public void parserInferenceIsWorking() throws Exception { + String filedir = "npm/prettier/filetypes/json/"; + + final String dirtyFile = filedir + "json.dirty"; + final String cleanFile = filedir + "json.clean"; + + final FormatterStep formatterStep = PrettierFormatterStep.create( + TestProvisioner.mavenCentral(), + buildDir(), + npmExecutable(), + new PrettierConfig(null, ImmutableMap.of("filepath", "anyname.json"))); // should select parser based on this name + + try (StepHarness stepHarness = StepHarness.forStep(formatterStep)) { + stepHarness.testResource(dirtyFile, cleanFile); + } } + } } diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/css/.prettierrc.yml b/lib-extra/src/test/resources/npm/prettier/filetypes/css/.prettierrc.yml new file mode 100644 index 0000000000..9919fdc796 --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/css/.prettierrc.yml @@ -0,0 +1 @@ +parser: postcss diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/css/css.clean b/lib-extra/src/test/resources/npm/prettier/filetypes/css/css.clean new file mode 100644 index 0000000000..c12c2d901a --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/css/css.clean @@ -0,0 +1,19 @@ +p, +#content, +.basic-text, +.custom-long-class-name, +.second-long-class-name, +.third-long-class-name, +.any-class { + font-size: 12 px; + padding: 0px 0px 0px 0px; +} + +div.layout-element { + padding-left: 5px; + padding-right: 5px; +} + +.almost-fullwidth { + width: calc(100%- 20px); +} diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/css/css.dirty b/lib-extra/src/test/resources/npm/prettier/filetypes/css/css.dirty new file mode 100644 index 0000000000..0824681c32 --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/css/css.dirty @@ -0,0 +1,20 @@ + + + +p, +#content,.basic-text,.custom-long-class-name,.second-long-class-name,.third-long-class-name,.any-class{ +font-size:12 px; + padding: 0px 0px 0px 0px; +} + + +div.layout-element { +padding-left:5px; padding-right:5px +} + + + + +.almost-fullwidth { +width:calc(100%- 20px) +} diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es5/.prettierrc.yml b/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es5/.prettierrc.yml new file mode 100644 index 0000000000..9bcfa0e0cb --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es5/.prettierrc.yml @@ -0,0 +1 @@ +parser: babylon diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es5/javascript-es5.clean b/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es5/javascript-es5.clean new file mode 100644 index 0000000000..3980a2f5fe --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es5/javascript-es5.clean @@ -0,0 +1,43 @@ +var numbers = [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20 +]; + +var p = { + first: "Peter", + last: "Pan", + get fullName() { + return this.first + " " + this.last; + } +}; + +var str = "Hello, world!"; + +var str2 = str.charAt(3) + str[0]; + +var multilinestr = "Hello \ +World"; + +function test(a, b) { + return a + b; +} + +test("Hello", "world"); diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es5/javascript-es5.dirty b/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es5/javascript-es5.dirty new file mode 100644 index 0000000000..11bbb93561 --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es5/javascript-es5.dirty @@ -0,0 +1,21 @@ +var numbers=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20, +]; + +var p = { + first: "Peter", + last : "Pan", + get fullName() { return this.first + " " + this.last; } +}; + +var str = "Hello, world!" +; + +var str2=str.charAt(3)+str[0]; + +var multilinestr = "Hello \ +World" +; + +function test (a, b) { return a+ b}; + +test ("Hello","world"); diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es6/.prettierrc.yml b/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es6/.prettierrc.yml new file mode 100644 index 0000000000..070afce294 --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es6/.prettierrc.yml @@ -0,0 +1 @@ +parser: flow diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es6/javascript-es6.clean b/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es6/javascript-es6.clean new file mode 100644 index 0000000000..5ee3f84fc3 --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es6/javascript-es6.clean @@ -0,0 +1,44 @@ +var numbers = [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20 +]; + +const p = { + first: "Peter", + last: "Pan", + get fullName() { + return this.first + " " + this.last; + } +}; + +const str = "Hello, world!"; + +var str2 = str.charAt(3) + str[0]; + +var multilinestr = "Hello \ +World"; + +function test(a, b = "world") { + let combined = a + b; + return combined; +} + +test("Hello"); diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es6/javascript-es6.dirty b/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es6/javascript-es6.dirty new file mode 100644 index 0000000000..08ebafc1a2 --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es6/javascript-es6.dirty @@ -0,0 +1,21 @@ +var numbers=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20, +]; + +const p = { + first: "Peter", + last : "Pan", + get fullName() { return this.first + " " + this.last; } +}; + +const str = "Hello, world!" +; + +var str2=str.charAt(3)+str[0]; + +var multilinestr = "Hello \ +World" +; + +function test (a, b = "world") { let combined =a+ b; return combined}; + +test ("Hello"); diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/json/.prettierrc.yml b/lib-extra/src/test/resources/npm/prettier/filetypes/json/.prettierrc.yml new file mode 100644 index 0000000000..21269cb2a5 --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/json/.prettierrc.yml @@ -0,0 +1 @@ +parser: json diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/json/json.clean b/lib-extra/src/test/resources/npm/prettier/filetypes/json/json.clean new file mode 100644 index 0000000000..a727382ec2 --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/json/json.clean @@ -0,0 +1,11 @@ +{ + "hello": "world", + "hello int": 123, + "hello array": ["1", "2", "3", "4"], + "hello object": { + "property1": "111111", + "property2": "2222222", + "property3": "333333333", + "property4": "44444444" + } +} diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/json/json.dirty b/lib-extra/src/test/resources/npm/prettier/filetypes/json/json.dirty new file mode 100644 index 0000000000..c16f934e78 --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/json/json.dirty @@ -0,0 +1 @@ +{ "hello": "world", "hello int": 123, "hello array":[ "1", "2", "3", "4"], "hello object":{ "property1":"111111","property2":"2222222","property3":"333333333","property4":"44444444"} } diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/markdown/.prettierrc.yml b/lib-extra/src/test/resources/npm/prettier/filetypes/markdown/.prettierrc.yml new file mode 100644 index 0000000000..fbc8c388e2 --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/markdown/.prettierrc.yml @@ -0,0 +1 @@ +parser: markdown diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/markdown/markdown.clean b/lib-extra/src/test/resources/npm/prettier/filetypes/markdown/markdown.clean new file mode 100644 index 0000000000..bf089b0eec --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/markdown/markdown.clean @@ -0,0 +1,21 @@ +# Title + +> Nested blockquotes +> +> > inner +> > +> > > even more inner + +- list +- list2 + - sublist sublist + * 2 + - 3 +- list3 + - sublist2 + - sublist2 + +Text text text +text text + +text2. diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/markdown/markdown.dirty b/lib-extra/src/test/resources/npm/prettier/filetypes/markdown/markdown.dirty new file mode 100644 index 0000000000..6a0c12c119 --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/markdown/markdown.dirty @@ -0,0 +1,20 @@ +# Title + +> Nested blockquotes +>> inner +>> > even more inner + + ++ list ++ list2 + - sublist sublist + * 2 + + 3 ++ list3 + - sublist2 + - sublist2 + +Text text text + text text + +text2. diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/scss/.prettierrc.yml b/lib-extra/src/test/resources/npm/prettier/filetypes/scss/.prettierrc.yml new file mode 100644 index 0000000000..9919fdc796 --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/scss/.prettierrc.yml @@ -0,0 +1 @@ +parser: postcss diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/scss/scss.clean b/lib-extra/src/test/resources/npm/prettier/filetypes/scss/scss.clean new file mode 100644 index 0000000000..2692f4221e --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/scss/scss.clean @@ -0,0 +1,35 @@ +p, +#content, +.basic-text, +.custom-long-class-name, +.second-long-class-name, +.third-long-class-name, +.any-class { + font-size: 12 px; + padding: 0px 0px 0px 0px; +} + +div.custom-layout { + div.layout-element { + padding-left: 5px; + padding-right: 5px; + } +} + +@mixin transform($property) { + -webkit-transform: $property; + -ms-transform: $property; + transform: $property; +} + +.box { + @include transform(rotate(30deg)); +} + +.almost-fullwidth { + width: calc(100%- 20px); +} + +.calculated-width { + width: 300px / 960px * 100%; +} diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/scss/scss.dirty b/lib-extra/src/test/resources/npm/prettier/filetypes/scss/scss.dirty new file mode 100644 index 0000000000..79b963af75 --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/scss/scss.dirty @@ -0,0 +1,34 @@ + + + +p, +#content,.basic-text,.custom-long-class-name,.second-long-class-name,.third-long-class-name,.any-class{ +font-size:12 px; + padding: 0px 0px 0px 0px; +} + + +div.custom-layout {div.layout-element { +padding-left:5px; padding-right:5px +}} + +@mixin transform($property) { -webkit-transform: $property; + -ms-transform: $property; + transform: $property; +} + + + + +.box { @include transform(rotate(30deg)); } + + +.almost-fullwidth { +width:calc(100%- 20px) +} + + + +.calculated-width { +width: 300px / 960px * 100% +} diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/typescript/.prettierrc.yml b/lib-extra/src/test/resources/npm/prettier/filetypes/typescript/.prettierrc.yml new file mode 100644 index 0000000000..dc710caa92 --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/typescript/.prettierrc.yml @@ -0,0 +1 @@ +parser: typescript diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/typescript/typescript.clean b/lib-extra/src/test/resources/npm/prettier/filetypes/typescript/typescript.clean new file mode 100644 index 0000000000..c8d17e7233 --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/typescript/typescript.clean @@ -0,0 +1,7 @@ +class Sample { + hello(word = "world") { + return "Hello, " + word; + } +} + +var s = new Sample(); diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/typescript/typescript.dirty b/lib-extra/src/test/resources/npm/prettier/filetypes/typescript/typescript.dirty new file mode 100644 index 0000000000..e2329f4f00 --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/filetypes/typescript/typescript.dirty @@ -0,0 +1,5 @@ +class Sample { +hello(word="world"){return "Hello, " + word;} +} + +var s=new Sample(); From d832ccd7ff1d42a895a89c754bd43e6a89762968 Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:51:40 +0200 Subject: [PATCH 20/45] test prettier configuration behavior --- .../extra/npm/PrettierFormatterStepTest.java | 38 ++++++++++++++++++- .../npm/prettier/config/.prettierrc.yml | 2 + .../config/typescript.configfile.clean | 15 ++++++++ .../prettier/config/typescript.defaults.clean | 11 ++++++ .../npm/prettier/config/typescript.dirty | 10 +++++ .../prettier/config/typescript.override.clean | 9 +++++ 6 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 lib-extra/src/test/resources/npm/prettier/config/.prettierrc.yml create mode 100644 lib-extra/src/test/resources/npm/prettier/config/typescript.configfile.clean create mode 100644 lib-extra/src/test/resources/npm/prettier/config/typescript.defaults.clean create mode 100644 lib-extra/src/test/resources/npm/prettier/config/typescript.dirty create mode 100644 lib-extra/src/test/resources/npm/prettier/config/typescript.override.clean diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java index ad12c9511c..43636563d4 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java @@ -83,7 +83,43 @@ public void parserInferenceIsWorking() throws Exception { stepHarness.testResource(dirtyFile, cleanFile); } } - } + @Category(NpmTest.class) + public static class PrettierFormattingOptionsAreWorking extends NpmFormatterStepCommonTests { + + private static final String FILEDIR = "npm/prettier/config/"; + + public void runFormatTest(PrettierConfig config, String cleanFileNameSuffix) throws Exception { + + final String dirtyFile = FILEDIR + "typescript.dirty"; + final String cleanFile = FILEDIR + "typescript." + cleanFileNameSuffix + ".clean"; + + final FormatterStep formatterStep = PrettierFormatterStep.create( + TestProvisioner.mavenCentral(), + buildDir(), + npmExecutable(), + config); // should select parser based on this name + + try (StepHarness stepHarness = StepHarness.forStep(formatterStep)) { + stepHarness.testResource(dirtyFile, cleanFile); + } + } + + @Test + public void defaultsAreApplied() throws Exception { + runFormatTest(new PrettierConfig(null, ImmutableMap.of("parser", "typescript")), "defaults"); + } + + @Test + public void configFileOptionsAreApplied() throws Exception { + runFormatTest(new PrettierConfig(createTestFile(FILEDIR + ".prettierrc.yml"), null), "configfile"); + } + + @Test + public void configFileOptionsCanBeOverriden() throws Exception { + runFormatTest(new PrettierConfig(createTestFile(FILEDIR + ".prettierrc.yml"), ImmutableMap.of("printWidth", 300)), "override"); + } + + } } diff --git a/lib-extra/src/test/resources/npm/prettier/config/.prettierrc.yml b/lib-extra/src/test/resources/npm/prettier/config/.prettierrc.yml new file mode 100644 index 0000000000..f078267520 --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/config/.prettierrc.yml @@ -0,0 +1,2 @@ +parser: typescript +printWidth: 50 diff --git a/lib-extra/src/test/resources/npm/prettier/config/typescript.configfile.clean b/lib-extra/src/test/resources/npm/prettier/config/typescript.configfile.clean new file mode 100644 index 0000000000..0ec76369be --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/config/typescript.configfile.clean @@ -0,0 +1,15 @@ +export class MyVeryOwnControllerWithARatherLongNameThatIsNotReallyNecessary + extends AbstractController + implements DisposeAware, CallbackAware { + public myValue: string[]; + + constructor( + private myService: Service, + name: string, + private field: any + ) { + super(name); + } + + //... +} diff --git a/lib-extra/src/test/resources/npm/prettier/config/typescript.defaults.clean b/lib-extra/src/test/resources/npm/prettier/config/typescript.defaults.clean new file mode 100644 index 0000000000..0155b905bd --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/config/typescript.defaults.clean @@ -0,0 +1,11 @@ +export class MyVeryOwnControllerWithARatherLongNameThatIsNotReallyNecessary + extends AbstractController + implements DisposeAware, CallbackAware { + public myValue: string[]; + + constructor(private myService: Service, name: string, private field: any) { + super(name); + } + + //... +} diff --git a/lib-extra/src/test/resources/npm/prettier/config/typescript.dirty b/lib-extra/src/test/resources/npm/prettier/config/typescript.dirty new file mode 100644 index 0000000000..a3a30bf49a --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/config/typescript.dirty @@ -0,0 +1,10 @@ +export class MyVeryOwnControllerWithARatherLongNameThatIsNotReallyNecessary extends AbstractController implements DisposeAware, CallbackAware { + + +public myValue:string[]; + +constructor(private myService:Service,name:string,private field:any){ super(name) ;} + + +//... +} diff --git a/lib-extra/src/test/resources/npm/prettier/config/typescript.override.clean b/lib-extra/src/test/resources/npm/prettier/config/typescript.override.clean new file mode 100644 index 0000000000..3f3a8c30af --- /dev/null +++ b/lib-extra/src/test/resources/npm/prettier/config/typescript.override.clean @@ -0,0 +1,9 @@ +export class MyVeryOwnControllerWithARatherLongNameThatIsNotReallyNecessary extends AbstractController implements DisposeAware, CallbackAware { + public myValue: string[]; + + constructor(private myService: Service, name: string, private field: any) { + super(name); + } + + //... +} From ff9a3d266380135f353bc1d48edc5a4e4c575cfe Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:52:00 +0200 Subject: [PATCH 21/45] auto-resolve npm binary (at least for tests very useful) --- .../extra/npm/NpmExecutableResolver.java | 102 ++++++++++++++++++ .../spotless/extra/npm/PlatformInfo.java | 28 ++++- .../npm/NpmFormatterStepCommonTests.java | 3 +- 3 files changed, 127 insertions(+), 6 deletions(-) create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmExecutableResolver.java diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmExecutableResolver.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmExecutableResolver.java new file mode 100644 index 0000000000..760f704727 --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmExecutableResolver.java @@ -0,0 +1,102 @@ +/* + * 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.extra.npm; + +import static com.diffplug.spotless.extra.npm.PlatformInfo.OS.WINDOWS; + +import java.io.File; +import java.util.Optional; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import com.diffplug.common.base.Splitter; + +/** + * Utility class to resolve an npm binary to be used by npm-based steps. + * Tries to find an npm executable in the following order: + *

    + *
  1. from System-Property {@code npm.exec} (unverified)
  2. + *
  3. from Environment-Properties in the following order:
  4. + *
      + *
    1. from NVM_BIN environment variable, if available
    2. + *
    3. from NODE_PATH environment variable, if available
    4. + *
    5. fallback: PATH environment variable
    6. + *
    + *
+ */ +class NpmExecutableResolver { + + private NpmExecutableResolver() { + // no instance + } + + static String npmExecutableName() { + String npmName = "npm"; + if (PlatformInfo.normalizedOS() == WINDOWS) { + npmName += ".exe"; + } + return npmName; + } + + static Supplier> systemProperty() { + return () -> Optional.ofNullable(System.getProperty("npm.exec")) + .map(File::new); + } + + static Supplier> environmentNvm() { + return () -> Optional.ofNullable(System.getenv("NVM_BIN")) + .map(File::new) + .map(binDir -> new File(binDir, npmExecutableName())) + .filter(File::exists) + .filter(File::canExecute); + } + + static Supplier> environmentNodepath() { + return pathListFromEnvironment("NODE_PATH"); + } + + static Supplier> environmentPath() { + return pathListFromEnvironment("PATH"); + } + + static Optional tryFind() { + return Stream.of(systemProperty(), environmentNvm(), environmentNodepath(), environmentPath()) + .map(Supplier::get) + .filter(Optional::isPresent) + .map(Optional::get) + .findFirst(); + } + + private static Supplier> pathListFromEnvironment(String environmentPathListName) { + return () -> { + String pathList = System.getenv(environmentPathListName); + if (pathList != null) { + return Splitter.on(System.getProperty("path.separator", ":")) + .splitToList(pathList) + .stream() + .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(); + }; + } + +} diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PlatformInfo.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PlatformInfo.java index 167bab6382..de49ca5f31 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PlatformInfo.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PlatformInfo.java @@ -15,6 +15,8 @@ */ package com.diffplug.spotless.extra.npm; +import static java.util.Objects.requireNonNull; + import java.util.Locale; import com.diffplug.common.base.StandardSystemProperty; @@ -24,24 +26,28 @@ private PlatformInfo() { // no instance } - static String normalizedOSName() { + static OS normalizedOS() { final String osNameProperty = StandardSystemProperty.OS_NAME.value(); if (osNameProperty == null) { throw new RuntimeException("No info about OS available, cannot decide which implementation of j2v8 to use"); } final String normalizedOsName = osNameProperty.toLowerCase(Locale.ENGLISH); if (normalizedOsName.contains("win")) { - return "win32"; + return OS.WINDOWS; } if (normalizedOsName.contains("mac")) { - return "macosx"; + return OS.MACOS; } if (normalizedOsName.contains("nix") || normalizedOsName.contains("nux") || normalizedOsName.contains("aix")) { - return "linux"; + return OS.LINUX; } throw new RuntimeException("Cannot handle os " + osNameProperty); } + static String normalizedOSName() { + return normalizedOS().normalizedOsName(); + } + static String normalizedArchName() { final String osArchProperty = StandardSystemProperty.OS_ARCH.value(); if (osArchProperty == null) { @@ -57,4 +63,18 @@ static String normalizedArchName() { } throw new RuntimeException("Cannot handle arch " + osArchProperty); } + + enum OS { + WINDOWS("win32"), MACOS("macosx"), LINUX("linux"); + + private final String normalizedOsName; + + OS(String normalizedOsName) { + this.normalizedOsName = requireNonNull(normalizedOsName); + } + + public String normalizedOsName() { + return normalizedOsName; + } + } } diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmFormatterStepCommonTests.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmFormatterStepCommonTests.java index 0be3bc7ec4..e519892c2a 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmFormatterStepCommonTests.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmFormatterStepCommonTests.java @@ -23,8 +23,7 @@ public abstract class NpmFormatterStepCommonTests extends ResourceHarness { protected File npmExecutable() { - // TODO (simschla, 24.08.18): read from System.property or the like? - return new File("/Users/simschla/.nvm/versions/node/v8.11.2/bin/npm"); + return NpmExecutableResolver.tryFind().orElseThrow(() -> new IllegalStateException("cannot detect node binary")); } private File buildDir = null; From 3dfe3c9281cc22b75d2ec9651be4bac2d68d47dc Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:52:20 +0200 Subject: [PATCH 22/45] adding gradle-integration for prettier --- .../extra/npm/NpmFormatterStepStateBase.java | 22 ++++++--- .../spotless/extra/npm/PrettierConfig.java | 6 ++- .../extra/npm/PrettierFormatterStep.java | 6 +-- .../gradle/spotless/FormatExtension.java | 47 +++++++++++++++++++ 4 files changed, 71 insertions(+), 10 deletions(-) diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java index eb5c03aa07..8b0c0e4b41 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java @@ -15,6 +15,7 @@ */ package com.diffplug.spotless.extra.npm; +import static com.diffplug.spotless.extra.npm.NpmExecutableResolver.tryFind; import static java.util.Objects.requireNonNull; import java.io.File; @@ -25,6 +26,9 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Optional; + +import javax.annotation.Nullable; import com.diffplug.spotless.*; @@ -46,16 +50,16 @@ public abstract class NpmFormatterStepStateBase implements Serializable { private final String stepName; - protected NpmFormatterStepStateBase(String stepName, Provisioner provisioner, NpmConfig npmConfig, File buildDir, File npm) throws IOException { - this.stepName = stepName; - this.npmConfig = npmConfig; + protected NpmFormatterStepStateBase(String stepName, Provisioner provisioner, NpmConfig npmConfig, File buildDir, @Nullable File npm) throws IOException { + this.stepName = requireNonNull(stepName); + this.npmConfig = requireNonNull(npmConfig); this.jarState = JarState.from(j2v8MavenCoordinate(), requireNonNull(provisioner)); this.nodeModulesDir = prepareNodeModules(buildDir, npm); this.nodeModulesSignature = FileSignature.signAsList(this.nodeModulesDir); } - private File prepareNodeModules(File buildDir, File npm) throws IOException { + private File prepareNodeModules(File buildDir, @Nullable File npm) throws IOException { File targetDir = new File(buildDir, "spotless-node-modules-" + stepName); if (!targetDir.exists()) { if (!targetDir.mkdirs()) { @@ -68,11 +72,11 @@ private File prepareNodeModules(File buildDir, File npm) throws IOException { return targetDir; } - private void runNpmInstall(File npm, File npmProjectDir) throws IOException { + private void runNpmInstall(@Nullable File npm, File npmProjectDir) throws IOException { Process npmInstall = new ProcessBuilder() .inheritIO() .directory(npmProjectDir) - .command(npm.getAbsolutePath(), "install") + .command(resolveNpm(npm).getAbsolutePath(), "install") .start(); try { if (npmInstall.waitFor() != 0) { @@ -83,6 +87,12 @@ private void runNpmInstall(File npm, File npmProjectDir) throws IOException { } } + private File resolveNpm(@Nullable File npm) { + return Optional.ofNullable(npm) + .orElseGet(() -> tryFind() + .orElseThrow(() -> new IllegalStateException("cannot automatically determine npm executable and none was specifically supplied!"))); + } + protected NodeJSWrapper nodeJSWrapper() { return new NodeJSWrapper(this.jarState.getClassLoader()); // TODO (simschla, 02.08.18): cache this instance } diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierConfig.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierConfig.java index 71e23306e1..214eec5d67 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierConfig.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierConfig.java @@ -21,6 +21,8 @@ import java.util.Map; import java.util.TreeMap; +import javax.annotation.Nullable; + import com.diffplug.spotless.FileSignature; import com.diffplug.spotless.ThrowingEx; @@ -31,6 +33,7 @@ public class PrettierConfig implements Serializable { private static final long serialVersionUID = -8709340269833126583L; @SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED") + @Nullable private final transient File prettierConfigPath; @SuppressWarnings("unused") @@ -38,7 +41,7 @@ public class PrettierConfig implements Serializable { private final TreeMap options; - public PrettierConfig(File prettierConfigPath, Map options) { + public PrettierConfig(@Nullable File prettierConfigPath, @Nullable Map options) { try { this.prettierConfigPath = prettierConfigPath; this.prettierConfigPathSignature = prettierConfigPath != null ? FileSignature.signAsList(this.prettierConfigPath) : FileSignature.signAsList(); @@ -48,6 +51,7 @@ public PrettierConfig(File prettierConfigPath, Map options) { } } + @Nullable public File getPrettierConfigPath() { return prettierConfigPath; } diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java index 0327bda015..f4e1e17c69 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java @@ -25,6 +25,7 @@ import java.util.TreeMap; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import com.diffplug.spotless.FormatterFunc; import com.diffplug.spotless.FormatterStep; @@ -35,10 +36,9 @@ public class PrettierFormatterStep { public static final String NAME = "prettier-format"; - public static FormatterStep create(Provisioner provisioner, File buildDir, File npm, PrettierConfig prettierConfig) { + public static FormatterStep create(Provisioner provisioner, File buildDir, @Nullable File npm, PrettierConfig prettierConfig) { requireNonNull(provisioner); requireNonNull(buildDir); - requireNonNull(npm); return FormatterStep.createLazy(NAME, () -> new State(NAME, provisioner, buildDir, npm, prettierConfig), State::createFormatterFunc); @@ -49,7 +49,7 @@ public static class State extends NpmFormatterStepStateBase implements Serializa private static final long serialVersionUID = -3811104513825329168L; private final PrettierConfig prettierConfig; - public State(String stepName, Provisioner provisioner, File buildDir, File npm, PrettierConfig prettierConfig) throws IOException { + State(String stepName, Provisioner provisioner, File buildDir, @Nullable File npm, PrettierConfig prettierConfig) throws IOException { super(stepName, provisioner, new NpmConfig( diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java index 7071dbd6ee..b8f074e372 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java @@ -40,6 +40,7 @@ import com.diffplug.spotless.LazyForwardingEquality; import com.diffplug.spotless.LineEnding; import com.diffplug.spotless.ThrowingEx; +import com.diffplug.spotless.extra.npm.PrettierFormatterStep; import com.diffplug.spotless.generic.EndWithNewlineStep; import com.diffplug.spotless.generic.IndentStep; import com.diffplug.spotless.generic.LicenseHeaderStep; @@ -430,6 +431,52 @@ public LicenseHeaderConfig licenseHeaderFile(Object licenseHeaderFile, String de return config; } + public class PrettierConfig { + @Nullable + private Object npmFile; + + @Nullable + private Object prettierConfigFile; + + @Nullable + private Map prettierConfig; + + public PrettierConfig npmExecutable(final Object npmFile) { + this.npmFile = npmFile; + replaceStep(createStep()); + return this; + } + + public PrettierConfig prettierConfigFile(final Object prettierConfigFile) { + this.prettierConfigFile = prettierConfigFile; + replaceStep(createStep()); + return this; + } + + public PrettierConfig prettierConfig(final Map prettierConfig) { + this.prettierConfig = prettierConfig; + replaceStep(createStep()); + return this; + } + + FormatterStep createStep() { + final Project project = getProject(); + return PrettierFormatterStep.create( + GradleProvisioner.fromProject(project), + project.getBuildDir(), + this.npmFile != null ? project.file(this.npmFile) : null, + new com.diffplug.spotless.extra.npm.PrettierConfig( + this.prettierConfigFile != null ? project.file(this.prettierConfigFile) : null, + this.prettierConfig)); + } + } + + public PrettierConfig prettier() { + final PrettierConfig prettierConfig = new PrettierConfig(); + addStep(prettierConfig.createStep()); + return prettierConfig; + } + /** Sets up a format task according to the values in this extension. */ protected void setupTask(SpotlessTask task) { task.setPaddedCell(paddedCell); From d21f2bcfff818418c3f6f7233aa1939acf7e2013 Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:52:36 +0200 Subject: [PATCH 23/45] adding gradle-integration for tsfmt --- .../gradle/spotless/FormatExtension.java | 33 ++++-- .../spotless/TypescriptGradleExtension.java | 100 ++++++++++++++++++ 2 files changed, 122 insertions(+), 11 deletions(-) create mode 100644 plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptGradleExtension.java diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java index b8f074e372..4d4d76116c 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java @@ -431,22 +431,33 @@ public LicenseHeaderConfig licenseHeaderFile(Object licenseHeaderFile, String de return config; } - public class PrettierConfig { + public abstract class NpmStepConfig { @Nullable - private Object npmFile; + protected Object npmFile; - @Nullable - private Object prettierConfigFile; - - @Nullable - private Map prettierConfig; - - public PrettierConfig npmExecutable(final Object npmFile) { + @SuppressWarnings("unchecked") + public T npmExecutable(final Object npmFile) { this.npmFile = npmFile; replaceStep(createStep()); - return this; + return (T) this; + } + + File npmFileOrNull() { + return npmFile != null ? getProject().file(npmFile) : null; } + abstract FormatterStep createStep(); + + } + + public class PrettierConfig extends NpmStepConfig { + + @Nullable + protected Object prettierConfigFile; + + @Nullable + protected Map prettierConfig; + public PrettierConfig prettierConfigFile(final Object prettierConfigFile) { this.prettierConfigFile = prettierConfigFile; replaceStep(createStep()); @@ -464,7 +475,7 @@ FormatterStep createStep() { return PrettierFormatterStep.create( GradleProvisioner.fromProject(project), project.getBuildDir(), - this.npmFile != null ? project.file(this.npmFile) : null, + npmFileOrNull(), new com.diffplug.spotless.extra.npm.PrettierConfig( this.prettierConfigFile != null ? project.file(this.prettierConfigFile) : null, this.prettierConfig)); diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptGradleExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptGradleExtension.java new file mode 100644 index 0000000000..cc92426c28 --- /dev/null +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptGradleExtension.java @@ -0,0 +1,100 @@ +/* + * 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.gradle.spotless; + +import java.util.Collections; +import java.util.Map; + +import javax.annotation.Nullable; + +import org.gradle.api.Project; + +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.extra.npm.TsFmtFormatterStep; + +public class TypescriptGradleExtension extends FormatExtension { + + static final String NAME = "typescript"; + + public TypescriptGradleExtension(SpotlessExtension root) { + super(root); + } + + public TypescriptFormatExtension tsfmt() { + TypescriptFormatExtension tsfmt = new TypescriptFormatExtension(); + addStep(tsfmt.createStep()); + return tsfmt; + } + + public class TypescriptFormatExtension extends NpmStepConfig { + + @Nullable + protected Map tsFmtConfig; + + public TypescriptFormatExtension config(Map config) { + this.tsFmtConfig = config; + replaceStep(createStep()); + return this; + } + + public FormatterStep createStep() { + final Project project = getProject(); + return TsFmtFormatterStep.create( + GradleProvisioner.fromProject(project), + project.getBuildDir(), + npmFileOrNull(), + tsFmtConfig); + } + } + + @Override + public PrettierConfig prettier() { + PrettierConfig prettierConfig = new TypescriptPrettierConfig(); + addStep(prettierConfig.createStep()); + return prettierConfig; + } + + /** + * Overrides the parser to be set to typescript, no matter what the user's config says. + */ + public class TypescriptPrettierConfig extends PrettierConfig { + @Override + FormatterStep createStep() { + fixParserToTypescript(); + return super.createStep(); + } + + private void fixParserToTypescript() { + if (this.prettierConfig == null) { + this.prettierConfig = Collections.singletonMap("parser", "typescript"); + } else { + final Object replaced = this.prettierConfig.put("parser", "typescript"); + if (replaced != null) { + getProject().getLogger().warn("overriding parser option to 'typescript'. Was set to '{}'", replaced); + } + } + } + } + + @Override + protected void setupTask(SpotlessTask task) { + // defaults to all typescript files + if (target == null) { + target = parseTarget("**/*.ts"); + } + super.setupTask(task); + } +} From 8b1cf97048cbe8cff145c884935217706cf84150 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Mon, 3 Sep 2018 22:59:37 -0700 Subject: [PATCH 24/45] Fix minor warnings in eclipse. --- .../spotless/extra/npm/BlacklistedOptionException.java | 1 + .../main/java/com/diffplug/spotless/extra/npm/Reflective.java | 2 ++ .../diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java | 3 ++- .../java/com/diffplug/gradle/spotless/FormatExtension.java | 2 +- testlib/src/main/java/com/diffplug/spotless/StepHarness.java | 2 +- 5 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/BlacklistedOptionException.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/BlacklistedOptionException.java index 83326cd9e0..d8e8d78289 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/BlacklistedOptionException.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/BlacklistedOptionException.java @@ -16,6 +16,7 @@ package com.diffplug.spotless.extra.npm; public class BlacklistedOptionException extends RuntimeException { + private static final long serialVersionUID = -5876348893394153811L; public BlacklistedOptionException(String blacklistedOption) { super("The config option '" + blacklistedOption + "' is not supported."); diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java index 55ccfc1905..c68fe43fb0 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java @@ -266,6 +266,8 @@ public int hashCode() { } public static class ReflectiveException extends RuntimeException { + private static final long serialVersionUID = -5764607170953013791L; + public ReflectiveException(String message, Throwable cause) { super(message, cause); } diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java index 121e0b4438..7ecb7179e8 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java @@ -88,7 +88,7 @@ public static Iterable blacklistedOption() { @Test(expected = BlacklistedOptionException.class) public void blacklistedOptionIsThrown() throws Exception { - final FormatterStep formatterStep = TsFmtFormatterStep.create( + TsFmtFormatterStep.create( TestProvisioner.mavenCentral(), buildDir(), npmExecutable(), @@ -97,6 +97,7 @@ ImmutableMap. builder() .build()); fail("should never be reached!"); + } } diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java index 4d4d76116c..7c66dd641d 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java @@ -431,7 +431,7 @@ public LicenseHeaderConfig licenseHeaderFile(Object licenseHeaderFile, String de return config; } - public abstract class NpmStepConfig { + public abstract class NpmStepConfig> { @Nullable protected Object npmFile; diff --git a/testlib/src/main/java/com/diffplug/spotless/StepHarness.java b/testlib/src/main/java/com/diffplug/spotless/StepHarness.java index fef037496d..a21c0f55f1 100644 --- a/testlib/src/main/java/com/diffplug/spotless/StepHarness.java +++ b/testlib/src/main/java/com/diffplug/spotless/StepHarness.java @@ -40,7 +40,7 @@ public static StepHarness forStep(FormatterStep step) { return new StepHarness(FormatterFunc.Closeable.of( () -> { if (step instanceof FormatterStepImpl.Standard) { - ((FormatterStepImpl.Standard) step).cleanupFormatterFunc(); + ((FormatterStepImpl.Standard) step).cleanupFormatterFunc(); } }, input -> LineEnding.toUnix(step.format(input, new File(""))))); From 18c774811b773d2205146f39c6d5d67e7d0c9541 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Mon, 3 Sep 2018 23:25:57 -0700 Subject: [PATCH 25/45] Made as much of the npm implementation package-private as possible. --- .../diffplug/spotless/extra/npm/BlacklistedOptionException.java | 2 +- .../java/com/diffplug/spotless/extra/npm/NodeJSWrapper.java | 2 +- .../main/java/com/diffplug/spotless/extra/npm/NpmConfig.java | 2 +- .../diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java | 2 +- .../diffplug/spotless/extra/npm/ReflectiveObjectWrapper.java | 2 +- .../java/com/diffplug/spotless/extra/npm/V8FunctionWrapper.java | 2 +- .../com/diffplug/spotless/extra/npm/V8ObjectUtilsWrapper.java | 2 +- .../java/com/diffplug/spotless/extra/npm/V8ObjectWrapper.java | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/BlacklistedOptionException.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/BlacklistedOptionException.java index d8e8d78289..f82751274d 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/BlacklistedOptionException.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/BlacklistedOptionException.java @@ -15,7 +15,7 @@ */ package com.diffplug.spotless.extra.npm; -public class BlacklistedOptionException extends RuntimeException { +class BlacklistedOptionException extends RuntimeException { private static final long serialVersionUID = -5876348893394153811L; public BlacklistedOptionException(String blacklistedOption) { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NodeJSWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NodeJSWrapper.java index ad76479eb2..407865680f 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NodeJSWrapper.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NodeJSWrapper.java @@ -19,7 +19,7 @@ import java.util.Map; import java.util.Objects; -public class NodeJSWrapper extends ReflectiveObjectWrapper { +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"; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmConfig.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmConfig.java index cc6bdc0d6b..768f995af5 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmConfig.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmConfig.java @@ -17,7 +17,7 @@ import java.io.Serializable; -public class NpmConfig implements Serializable { +class NpmConfig implements Serializable { private static final long serialVersionUID = -1866722789779160491L; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java index 8b0c0e4b41..23bc688585 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java @@ -34,7 +34,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -public abstract class NpmFormatterStepStateBase implements Serializable { +abstract class NpmFormatterStepStateBase implements Serializable { private static final long serialVersionUID = -5849375492831208496L; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/ReflectiveObjectWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/ReflectiveObjectWrapper.java index d0e5b56dcd..e10b23a366 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/ReflectiveObjectWrapper.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/ReflectiveObjectWrapper.java @@ -20,7 +20,7 @@ import java.util.Objects; import java.util.function.Function; -public abstract class ReflectiveObjectWrapper implements AutoCloseable { +abstract class ReflectiveObjectWrapper implements AutoCloseable { private final Object wrappedObj; private final Reflective reflective; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8FunctionWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8FunctionWrapper.java index b305d5bdd3..9eefa13a61 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8FunctionWrapper.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8FunctionWrapper.java @@ -17,7 +17,7 @@ import java.lang.reflect.Method; -public class V8FunctionWrapper extends ReflectiveObjectWrapper { +class V8FunctionWrapper extends ReflectiveObjectWrapper { public static final String WRAPPED_CLASS = "com.eclipsesource.v8.V8Function"; public static final String CALLBACK_WRAPPED_CLASS = "com.eclipsesource.v8.JavaCallback"; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectUtilsWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectUtilsWrapper.java index 373233fd47..0bd785795f 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectUtilsWrapper.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectUtilsWrapper.java @@ -19,7 +19,7 @@ import java.util.Map; -public class V8ObjectUtilsWrapper { +class V8ObjectUtilsWrapper { public static final String WRAPPED_CLASS = "com.eclipsesource.v8.utils.V8ObjectUtils"; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectWrapper.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectWrapper.java index 95aa9bc2e0..ca5d69eaa1 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectWrapper.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectWrapper.java @@ -17,7 +17,7 @@ import java.util.Optional; -public class V8ObjectWrapper extends ReflectiveObjectWrapper { +class V8ObjectWrapper extends ReflectiveObjectWrapper { public static final String WRAPPED_CLASS = "com.eclipsesource.v8.V8Object"; From 555017429adde688c546a0cde7c3f6e429652729 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Mon, 3 Sep 2018 23:27:48 -0700 Subject: [PATCH 26/45] Fixed the gradle typescript extension. --- .../java/com/diffplug/gradle/spotless/SpotlessExtension.java | 5 +++++ ...pescriptGradleExtension.java => TypescriptExtension.java} | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) rename plugin-gradle/src/main/java/com/diffplug/gradle/spotless/{TypescriptGradleExtension.java => TypescriptExtension.java} (95%) diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java index 15877034d9..686989b764 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java @@ -118,6 +118,11 @@ public void sql(Action closure) { configure(SqlExtension.NAME, SqlExtension.class, closure); } + /** Configures the special typescript-specific extension for SQL files. */ + public void typescript(Action closure) { + configure(TypescriptExtension.NAME, TypescriptExtension.class, closure); + } + /** Configures a custom extension. */ public void format(String name, Action closure) { requireNonNull(name, "name"); diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptGradleExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java similarity index 95% rename from plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptGradleExtension.java rename to plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java index cc92426c28..75e8df69e0 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptGradleExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java @@ -25,11 +25,11 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.extra.npm.TsFmtFormatterStep; -public class TypescriptGradleExtension extends FormatExtension { +public class TypescriptExtension extends FormatExtension { static final String NAME = "typescript"; - public TypescriptGradleExtension(SpotlessExtension root) { + public TypescriptExtension(SpotlessExtension root) { super(root); } From 092a48880861085d97e253b7e04462515aba872f Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Mon, 3 Sep 2018 23:44:33 -0700 Subject: [PATCH 27/45] Make the npm tests run on CI. --- .ci/ci.sh | 1 + .travis.yml | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.ci/ci.sh b/.ci/ci.sh index 075a3abb43..15b6f70870 100755 --- a/.ci/ci.sh +++ b/.ci/ci.sh @@ -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 diff --git a/.travis.yml b/.travis.yml index 5de9f5b2c5..267295353f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 From 83178d1615dd8c7ab4418b6ee9db37a2761987c0 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Tue, 4 Sep 2018 00:07:24 -0700 Subject: [PATCH 28/45] Moved all of npm's test files into testlib so that they can be reused in integration tests. --- .../src/main}/resources/npm/prettier/config/.prettierrc.yml | 0 .../resources/npm/prettier/config/typescript.configfile.clean | 0 .../main}/resources/npm/prettier/config/typescript.defaults.clean | 0 .../src/main}/resources/npm/prettier/config/typescript.dirty | 0 .../main}/resources/npm/prettier/config/typescript.override.clean | 0 .../main}/resources/npm/prettier/filetypes/css/.prettierrc.yml | 0 .../src/main}/resources/npm/prettier/filetypes/css/css.clean | 0 .../src/main}/resources/npm/prettier/filetypes/css/css.dirty | 0 .../npm/prettier/filetypes/javascript-es5/.prettierrc.yml | 0 .../npm/prettier/filetypes/javascript-es5/javascript-es5.clean | 0 .../npm/prettier/filetypes/javascript-es5/javascript-es5.dirty | 0 .../npm/prettier/filetypes/javascript-es6/.prettierrc.yml | 0 .../npm/prettier/filetypes/javascript-es6/javascript-es6.clean | 0 .../npm/prettier/filetypes/javascript-es6/javascript-es6.dirty | 0 .../main}/resources/npm/prettier/filetypes/json/.prettierrc.yml | 0 .../src/main}/resources/npm/prettier/filetypes/json/json.clean | 0 .../src/main}/resources/npm/prettier/filetypes/json/json.dirty | 0 .../resources/npm/prettier/filetypes/markdown/.prettierrc.yml | 0 .../resources/npm/prettier/filetypes/markdown/markdown.clean | 0 .../resources/npm/prettier/filetypes/markdown/markdown.dirty | 0 .../main}/resources/npm/prettier/filetypes/scss/.prettierrc.yml | 0 .../src/main}/resources/npm/prettier/filetypes/scss/scss.clean | 0 .../src/main}/resources/npm/prettier/filetypes/scss/scss.dirty | 0 .../resources/npm/prettier/filetypes/typescript/.prettierrc.yml | 0 .../resources/npm/prettier/filetypes/typescript/typescript.clean | 0 .../resources/npm/prettier/filetypes/typescript/typescript.dirty | 0 .../src/main}/resources/npm/tsfmt/tsconfig/tsconfig.clean | 0 .../src/main}/resources/npm/tsfmt/tsconfig/tsconfig.dirty | 0 .../src/main}/resources/npm/tsfmt/tsconfig/tsconfig.json | 0 .../src/main}/resources/npm/tsfmt/tsfmt/tsfmt.clean | 0 .../src/main}/resources/npm/tsfmt/tsfmt/tsfmt.dirty | 0 .../src/main}/resources/npm/tsfmt/tsfmt/tsfmt.json | 0 .../src/main}/resources/npm/tsfmt/tslint/tslint.clean | 0 .../src/main}/resources/npm/tsfmt/tslint/tslint.dirty | 0 .../src/main}/resources/npm/tsfmt/tslint/tslint.json | 0 .../src/main}/resources/npm/tsfmt/vscode/vscode.clean | 0 .../src/main}/resources/npm/tsfmt/vscode/vscode.dirty | 0 .../src/main}/resources/npm/tsfmt/vscode/vscode.json | 0 38 files changed, 0 insertions(+), 0 deletions(-) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/config/.prettierrc.yml (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/config/typescript.configfile.clean (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/config/typescript.defaults.clean (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/config/typescript.dirty (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/config/typescript.override.clean (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/css/.prettierrc.yml (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/css/css.clean (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/css/css.dirty (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/javascript-es5/.prettierrc.yml (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/javascript-es5/javascript-es5.clean (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/javascript-es5/javascript-es5.dirty (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/javascript-es6/.prettierrc.yml (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/javascript-es6/javascript-es6.clean (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/javascript-es6/javascript-es6.dirty (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/json/.prettierrc.yml (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/json/json.clean (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/json/json.dirty (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/markdown/.prettierrc.yml (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/markdown/markdown.clean (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/markdown/markdown.dirty (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/scss/.prettierrc.yml (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/scss/scss.clean (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/scss/scss.dirty (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/typescript/.prettierrc.yml (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/typescript/typescript.clean (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/prettier/filetypes/typescript/typescript.dirty (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/tsfmt/tsconfig/tsconfig.clean (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/tsfmt/tsconfig/tsconfig.dirty (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/tsfmt/tsconfig/tsconfig.json (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/tsfmt/tsfmt/tsfmt.clean (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/tsfmt/tsfmt/tsfmt.dirty (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/tsfmt/tsfmt/tsfmt.json (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/tsfmt/tslint/tslint.clean (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/tsfmt/tslint/tslint.dirty (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/tsfmt/tslint/tslint.json (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/tsfmt/vscode/vscode.clean (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/tsfmt/vscode/vscode.dirty (100%) rename {lib-extra/src/test => testlib/src/main}/resources/npm/tsfmt/vscode/vscode.json (100%) diff --git a/lib-extra/src/test/resources/npm/prettier/config/.prettierrc.yml b/testlib/src/main/resources/npm/prettier/config/.prettierrc.yml similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/config/.prettierrc.yml rename to testlib/src/main/resources/npm/prettier/config/.prettierrc.yml diff --git a/lib-extra/src/test/resources/npm/prettier/config/typescript.configfile.clean b/testlib/src/main/resources/npm/prettier/config/typescript.configfile.clean similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/config/typescript.configfile.clean rename to testlib/src/main/resources/npm/prettier/config/typescript.configfile.clean diff --git a/lib-extra/src/test/resources/npm/prettier/config/typescript.defaults.clean b/testlib/src/main/resources/npm/prettier/config/typescript.defaults.clean similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/config/typescript.defaults.clean rename to testlib/src/main/resources/npm/prettier/config/typescript.defaults.clean diff --git a/lib-extra/src/test/resources/npm/prettier/config/typescript.dirty b/testlib/src/main/resources/npm/prettier/config/typescript.dirty similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/config/typescript.dirty rename to testlib/src/main/resources/npm/prettier/config/typescript.dirty diff --git a/lib-extra/src/test/resources/npm/prettier/config/typescript.override.clean b/testlib/src/main/resources/npm/prettier/config/typescript.override.clean similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/config/typescript.override.clean rename to testlib/src/main/resources/npm/prettier/config/typescript.override.clean diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/css/.prettierrc.yml b/testlib/src/main/resources/npm/prettier/filetypes/css/.prettierrc.yml similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/css/.prettierrc.yml rename to testlib/src/main/resources/npm/prettier/filetypes/css/.prettierrc.yml diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/css/css.clean b/testlib/src/main/resources/npm/prettier/filetypes/css/css.clean similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/css/css.clean rename to testlib/src/main/resources/npm/prettier/filetypes/css/css.clean diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/css/css.dirty b/testlib/src/main/resources/npm/prettier/filetypes/css/css.dirty similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/css/css.dirty rename to testlib/src/main/resources/npm/prettier/filetypes/css/css.dirty diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es5/.prettierrc.yml b/testlib/src/main/resources/npm/prettier/filetypes/javascript-es5/.prettierrc.yml similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es5/.prettierrc.yml rename to testlib/src/main/resources/npm/prettier/filetypes/javascript-es5/.prettierrc.yml diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es5/javascript-es5.clean b/testlib/src/main/resources/npm/prettier/filetypes/javascript-es5/javascript-es5.clean similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es5/javascript-es5.clean rename to testlib/src/main/resources/npm/prettier/filetypes/javascript-es5/javascript-es5.clean diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es5/javascript-es5.dirty b/testlib/src/main/resources/npm/prettier/filetypes/javascript-es5/javascript-es5.dirty similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es5/javascript-es5.dirty rename to testlib/src/main/resources/npm/prettier/filetypes/javascript-es5/javascript-es5.dirty diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es6/.prettierrc.yml b/testlib/src/main/resources/npm/prettier/filetypes/javascript-es6/.prettierrc.yml similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es6/.prettierrc.yml rename to testlib/src/main/resources/npm/prettier/filetypes/javascript-es6/.prettierrc.yml diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es6/javascript-es6.clean b/testlib/src/main/resources/npm/prettier/filetypes/javascript-es6/javascript-es6.clean similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es6/javascript-es6.clean rename to testlib/src/main/resources/npm/prettier/filetypes/javascript-es6/javascript-es6.clean diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es6/javascript-es6.dirty b/testlib/src/main/resources/npm/prettier/filetypes/javascript-es6/javascript-es6.dirty similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/javascript-es6/javascript-es6.dirty rename to testlib/src/main/resources/npm/prettier/filetypes/javascript-es6/javascript-es6.dirty diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/json/.prettierrc.yml b/testlib/src/main/resources/npm/prettier/filetypes/json/.prettierrc.yml similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/json/.prettierrc.yml rename to testlib/src/main/resources/npm/prettier/filetypes/json/.prettierrc.yml diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/json/json.clean b/testlib/src/main/resources/npm/prettier/filetypes/json/json.clean similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/json/json.clean rename to testlib/src/main/resources/npm/prettier/filetypes/json/json.clean diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/json/json.dirty b/testlib/src/main/resources/npm/prettier/filetypes/json/json.dirty similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/json/json.dirty rename to testlib/src/main/resources/npm/prettier/filetypes/json/json.dirty diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/markdown/.prettierrc.yml b/testlib/src/main/resources/npm/prettier/filetypes/markdown/.prettierrc.yml similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/markdown/.prettierrc.yml rename to testlib/src/main/resources/npm/prettier/filetypes/markdown/.prettierrc.yml diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/markdown/markdown.clean b/testlib/src/main/resources/npm/prettier/filetypes/markdown/markdown.clean similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/markdown/markdown.clean rename to testlib/src/main/resources/npm/prettier/filetypes/markdown/markdown.clean diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/markdown/markdown.dirty b/testlib/src/main/resources/npm/prettier/filetypes/markdown/markdown.dirty similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/markdown/markdown.dirty rename to testlib/src/main/resources/npm/prettier/filetypes/markdown/markdown.dirty diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/scss/.prettierrc.yml b/testlib/src/main/resources/npm/prettier/filetypes/scss/.prettierrc.yml similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/scss/.prettierrc.yml rename to testlib/src/main/resources/npm/prettier/filetypes/scss/.prettierrc.yml diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/scss/scss.clean b/testlib/src/main/resources/npm/prettier/filetypes/scss/scss.clean similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/scss/scss.clean rename to testlib/src/main/resources/npm/prettier/filetypes/scss/scss.clean diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/scss/scss.dirty b/testlib/src/main/resources/npm/prettier/filetypes/scss/scss.dirty similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/scss/scss.dirty rename to testlib/src/main/resources/npm/prettier/filetypes/scss/scss.dirty diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/typescript/.prettierrc.yml b/testlib/src/main/resources/npm/prettier/filetypes/typescript/.prettierrc.yml similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/typescript/.prettierrc.yml rename to testlib/src/main/resources/npm/prettier/filetypes/typescript/.prettierrc.yml diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/typescript/typescript.clean b/testlib/src/main/resources/npm/prettier/filetypes/typescript/typescript.clean similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/typescript/typescript.clean rename to testlib/src/main/resources/npm/prettier/filetypes/typescript/typescript.clean diff --git a/lib-extra/src/test/resources/npm/prettier/filetypes/typescript/typescript.dirty b/testlib/src/main/resources/npm/prettier/filetypes/typescript/typescript.dirty similarity index 100% rename from lib-extra/src/test/resources/npm/prettier/filetypes/typescript/typescript.dirty rename to testlib/src/main/resources/npm/prettier/filetypes/typescript/typescript.dirty diff --git a/lib-extra/src/test/resources/npm/tsfmt/tsconfig/tsconfig.clean b/testlib/src/main/resources/npm/tsfmt/tsconfig/tsconfig.clean similarity index 100% rename from lib-extra/src/test/resources/npm/tsfmt/tsconfig/tsconfig.clean rename to testlib/src/main/resources/npm/tsfmt/tsconfig/tsconfig.clean diff --git a/lib-extra/src/test/resources/npm/tsfmt/tsconfig/tsconfig.dirty b/testlib/src/main/resources/npm/tsfmt/tsconfig/tsconfig.dirty similarity index 100% rename from lib-extra/src/test/resources/npm/tsfmt/tsconfig/tsconfig.dirty rename to testlib/src/main/resources/npm/tsfmt/tsconfig/tsconfig.dirty diff --git a/lib-extra/src/test/resources/npm/tsfmt/tsconfig/tsconfig.json b/testlib/src/main/resources/npm/tsfmt/tsconfig/tsconfig.json similarity index 100% rename from lib-extra/src/test/resources/npm/tsfmt/tsconfig/tsconfig.json rename to testlib/src/main/resources/npm/tsfmt/tsconfig/tsconfig.json diff --git a/lib-extra/src/test/resources/npm/tsfmt/tsfmt/tsfmt.clean b/testlib/src/main/resources/npm/tsfmt/tsfmt/tsfmt.clean similarity index 100% rename from lib-extra/src/test/resources/npm/tsfmt/tsfmt/tsfmt.clean rename to testlib/src/main/resources/npm/tsfmt/tsfmt/tsfmt.clean diff --git a/lib-extra/src/test/resources/npm/tsfmt/tsfmt/tsfmt.dirty b/testlib/src/main/resources/npm/tsfmt/tsfmt/tsfmt.dirty similarity index 100% rename from lib-extra/src/test/resources/npm/tsfmt/tsfmt/tsfmt.dirty rename to testlib/src/main/resources/npm/tsfmt/tsfmt/tsfmt.dirty diff --git a/lib-extra/src/test/resources/npm/tsfmt/tsfmt/tsfmt.json b/testlib/src/main/resources/npm/tsfmt/tsfmt/tsfmt.json similarity index 100% rename from lib-extra/src/test/resources/npm/tsfmt/tsfmt/tsfmt.json rename to testlib/src/main/resources/npm/tsfmt/tsfmt/tsfmt.json diff --git a/lib-extra/src/test/resources/npm/tsfmt/tslint/tslint.clean b/testlib/src/main/resources/npm/tsfmt/tslint/tslint.clean similarity index 100% rename from lib-extra/src/test/resources/npm/tsfmt/tslint/tslint.clean rename to testlib/src/main/resources/npm/tsfmt/tslint/tslint.clean diff --git a/lib-extra/src/test/resources/npm/tsfmt/tslint/tslint.dirty b/testlib/src/main/resources/npm/tsfmt/tslint/tslint.dirty similarity index 100% rename from lib-extra/src/test/resources/npm/tsfmt/tslint/tslint.dirty rename to testlib/src/main/resources/npm/tsfmt/tslint/tslint.dirty diff --git a/lib-extra/src/test/resources/npm/tsfmt/tslint/tslint.json b/testlib/src/main/resources/npm/tsfmt/tslint/tslint.json similarity index 100% rename from lib-extra/src/test/resources/npm/tsfmt/tslint/tslint.json rename to testlib/src/main/resources/npm/tsfmt/tslint/tslint.json diff --git a/lib-extra/src/test/resources/npm/tsfmt/vscode/vscode.clean b/testlib/src/main/resources/npm/tsfmt/vscode/vscode.clean similarity index 100% rename from lib-extra/src/test/resources/npm/tsfmt/vscode/vscode.clean rename to testlib/src/main/resources/npm/tsfmt/vscode/vscode.clean diff --git a/lib-extra/src/test/resources/npm/tsfmt/vscode/vscode.dirty b/testlib/src/main/resources/npm/tsfmt/vscode/vscode.dirty similarity index 100% rename from lib-extra/src/test/resources/npm/tsfmt/vscode/vscode.dirty rename to testlib/src/main/resources/npm/tsfmt/vscode/vscode.dirty diff --git a/lib-extra/src/test/resources/npm/tsfmt/vscode/vscode.json b/testlib/src/main/resources/npm/tsfmt/vscode/vscode.json similarity index 100% rename from lib-extra/src/test/resources/npm/tsfmt/vscode/vscode.json rename to testlib/src/main/resources/npm/tsfmt/vscode/vscode.json From ded58853733cebad048de8d9052e5b8c105e4c9d Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Tue, 4 Sep 2018 00:32:57 -0700 Subject: [PATCH 29/45] readFileFromClasspath is now compatible with the gradle classpath --- .../extra/npm/NpmFormatterStepStateBase.java | 26 ++++++++++++------- .../extra/npm/PrettierFormatterStep.java | 2 +- .../extra/npm/TsFmtFormatterStep.java | 13 ++++++---- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java index 23bc688585..94f7e68222 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java @@ -18,19 +18,22 @@ import static com.diffplug.spotless.extra.npm.NpmExecutableResolver.tryFind; import static java.util.Objects.requireNonNull; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.io.Serializable; -import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.Optional; import javax.annotation.Nullable; -import com.diffplug.spotless.*; +import com.diffplug.common.base.Errors; +import com.diffplug.spotless.FileSignature; +import com.diffplug.spotless.FormatterFunc; +import com.diffplug.spotless.JarState; +import com.diffplug.spotless.Provisioner; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -106,11 +109,16 @@ private String j2v8MavenCoordinate() { } protected static String readFileFromClasspath(Class clazz, String name) { - try { - Path path = Paths.get(clazz.getResource(name).toURI()); - return new String(Files.readAllBytes(path), StandardCharsets.UTF_8); - } catch (URISyntaxException | IOException e) { - throw ThrowingEx.asRuntime(e); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + try (InputStream input = clazz.getResourceAsStream(name)) { + byte[] buffer = new byte[1024]; + int numRead; + while ((numRead = input.read(buffer)) != -1) { + output.write(buffer, 0, numRead); + } + return output.toString(StandardCharsets.UTF_8.name()); + } catch (IOException e) { + throw Errors.asRuntime(e); } } diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java index f4e1e17c69..153bc7e229 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java @@ -53,7 +53,7 @@ public static class State extends NpmFormatterStepStateBase implements Serializa super(stepName, provisioner, new NpmConfig( - readFileFromClasspath(PrettierFormatterStep.class, "prettier-package.json"), + readFileFromClasspath(PrettierFormatterStep.class, "/com/diffplug/spotless/extra/npm/prettier-package.json"), "prettier"), buildDir, npm); diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java index 0f08b105a4..5f9a4830d1 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java @@ -21,9 +21,13 @@ import java.io.File; import java.io.IOException; import java.io.Serializable; -import java.util.*; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import com.diffplug.spotless.FormatterFunc; import com.diffplug.spotless.FormatterStep; @@ -34,10 +38,9 @@ public class TsFmtFormatterStep { public static final String NAME = "tsfmt-format"; - public static FormatterStep create(Provisioner provisioner, File buildDir, File npm, Map tsFmtOptions) { + public static FormatterStep create(Provisioner provisioner, File buildDir, @Nullable File npm, Map tsFmtOptions) { requireNonNull(provisioner); requireNonNull(buildDir); - requireNonNull(npm); validateOptions(requireNonNull(tsFmtOptions)); return FormatterStep.createLazy(NAME, () -> new State(NAME, provisioner, buildDir, npm, tsFmtOptions), @@ -59,11 +62,11 @@ public static class State extends NpmFormatterStepStateBase implements Serializa private final TreeMap tsFmtOptions; - public State(String stepName, Provisioner provisioner, File buildDir, File npm, Map tsFmtOptions) throws IOException { + public State(String stepName, Provisioner provisioner, File buildDir, @Nullable File npm, Map tsFmtOptions) throws IOException { super(stepName, provisioner, new NpmConfig( - readFileFromClasspath(TsFmtFormatterStep.class, "tsfmt-package.json"), + readFileFromClasspath(TsFmtFormatterStep.class, "/com/diffplug/spotless/extra/npm/tsfmt-package.json"), "typescript-formatter"), buildDir, npm); From 4ee647e553452acfd64409b012b7b2a0adeea891 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Tue, 4 Sep 2018 00:46:20 -0700 Subject: [PATCH 30/45] Added an integration test for TypescriptExtension, but it doesn't pass. Seems that I'm misunderstanding something... --- plugin-gradle/build.gradle | 4 ++ .../gradle/spotless/TypescriptExtension.java | 5 +-- .../com/diffplug/gradle/spotless/NpmTest.java | 20 +++++++++ .../spotless/TypescriptExtensionTest.java | 45 +++++++++++++++++++ 4 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 plugin-gradle/src/test/java/com/diffplug/gradle/spotless/NpmTest.java create mode 100644 plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java diff --git a/plugin-gradle/build.gradle b/plugin-gradle/build.gradle index ef13f70de5..eb405d7b27 100644 --- a/plugin-gradle/build.gradle +++ b/plugin-gradle/build.gradle @@ -41,6 +41,10 @@ task spotlessApply(type: JavaExec) { } test { testLogging.showStandardStreams = true } +test { useJUnit { excludeCategories 'com.diffplug.spotless.extra.npm.NpmTest' } } + +task npmTest(type: Test) { useJUnit { includeCategories 'com.diffplug.gradle.spotless.NpmTest' } } + ////////////////////////// // GRADLE PLUGIN PORTAL // ////////////////////////// diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java index 75e8df69e0..23b4b3f044 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java @@ -18,8 +18,6 @@ import java.util.Collections; import java.util.Map; -import javax.annotation.Nullable; - import org.gradle.api.Project; import com.diffplug.spotless.FormatterStep; @@ -41,8 +39,7 @@ public TypescriptFormatExtension tsfmt() { public class TypescriptFormatExtension extends NpmStepConfig { - @Nullable - protected Map tsFmtConfig; + protected Map tsFmtConfig = Collections.emptyMap(); public TypescriptFormatExtension config(Map config) { this.tsFmtConfig = config; diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/NpmTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/NpmTest.java new file mode 100644 index 0000000000..a2bc84b43c --- /dev/null +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/NpmTest.java @@ -0,0 +1,20 @@ +/* + * 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.gradle.spotless; + +public interface NpmTest { + +} diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java new file mode 100644 index 0000000000..dcd280a6a0 --- /dev/null +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java @@ -0,0 +1,45 @@ +/* + * 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.gradle.spotless; + +import java.io.IOException; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(NpmTest.class) +public class TypescriptExtensionTest extends GradleIntegrationTest { + @Test + public void integration() throws IOException { + setFile("build.gradle").toLines( + "buildscript { repositories { mavenCentral() } }", + "plugins {", + " id 'com.diffplug.gradle.spotless'", + "}", + "def tsfmtconfig = [:]", + "tsfmtconfig['indentSize'] = 1", + "tsfmtconfig['convertTabsToSpaces'] = true", + "spotless {", + " typescript {", + " target 'test.ts'", + " tsfmt().config(tsfmtconfig)", + " }", + "}"); + setFile("test.ts").toResource("npm/tsfmt/tsfmt/tsfmt.dirty"); + gradleRunner().withArguments("spotlessApply").build(); + assertFile("test.ts").sameAsResource("npm/tsfmt/tsfmt/tsfmt.clean"); + } +} From 0b604ab2e37d4ffb5958de717acf6342b8e71498 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Tue, 4 Sep 2018 00:48:30 -0700 Subject: [PATCH 31/45] A super incomplete version of the docs, to plant the seed. --- README.md | 6 +++++- plugin-gradle/README.md | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 310a9d0e49..6773e86be7 100644 --- a/README.md +++ b/README.md @@ -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)) -Spotless can format <java | kotlin | scala | sql | groovy | markdown | license headers | anything> using <gradle | maven | anything>. +Spotless can format <java | kotlin | scala | sql | groovy | javascript | flow | typeScript | css | scss | less | jsx | vue | graphql | json | yaml | markdown | license headers | anything> using <gradle | maven | anything>. - [Spotless for Gradle](plugin-gradle) - [Spotless for Maven](plugin-maven) @@ -45,6 +45,8 @@ lib('java.RemoveUnusedImportsStep') +'{{yes}} | {{yes}} extra('java.EclipseFormatterStep') +'{{yes}} | {{yes}} | {{no}} |', lib('kotlin.KtLintStep') +'{{yes}} | {{yes}} | {{no}} |', lib('markdown.FreshMarkStep') +'{{yes}} | {{no}} | {{no}} |', +extra('npm.PrettierFormatterStep') +'{{yes}} | {{no}} | {{no}} |', +extra('npm.TsFmtFormatterStep') +'{{yes}} | {{no}} | {{no}} |', lib('scala.ScalaFmtStep') +'{{yes}} | {{yes}} | {{no}} |', lib('sql.DBeaverSQLFormatterStep') +'{{yes}} | {{no}} | {{no}} |', '| [(Your FormatterStep here)](CONTRIBUTING.md#how-to-add-a-new-formatterstep) | {{no}} | {{no}} | {{no}} |', @@ -68,6 +70,8 @@ lib('sql.DBeaverSQLFormatterStep') +'{{yes}} | {{no}} | [`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-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java) | :+1: | :white_large_square: | :white_large_square: | +| [`npm.TsFmtFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/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: | | [(Your FormatterStep here)](CONTRIBUTING.md#how-to-add-a-new-formatterstep) | :white_large_square: | :white_large_square: | :white_large_square: | diff --git a/plugin-gradle/README.md b/plugin-gradle/README.md index 8f84884712..f01d015ec7 100644 --- a/plugin-gradle/README.md +++ b/plugin-gradle/README.md @@ -333,6 +333,46 @@ spotless { } ``` + + +## Applying [prettier](https://prettier.io/) to javascript | flow | typeScript | css | scss | less | jsx | etc. + +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. + +```gradle +spotless { + format 'css', { + target 'src/main/resources/**/*.css' + prettier().prettierConfig([type: 'css']) + } +} +``` + +To apply prettier to more kinds of files, just add more formats + +```gradle +spotless { + format 'javascript', { + target 'src/main/resources/**/*.js' + prettier().prettierConfig([type: 'js']) + } +} +``` + + + +## Applying [tsfmt](https://github.com/vvakame/typescript-formatter) to typescript + +To use tsfmt, you first have to specify the files that you want it to apply to. Then you specify `tsfmt()`, and optionally how you want to apply it. + +```gradle +spotless { + typescript { + target 'src/main/resources/**/*.ts' + tsfmt().config([type: 'something']) + } +} +``` From 2197c27a3dde3852d4199dc1c4db3fc4c023797f Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:53:40 +0200 Subject: [PATCH 32/45] first documentation draft --- plugin-gradle/README.md | 166 +++++++++++++++++++++++++++++++--------- 1 file changed, 130 insertions(+), 36 deletions(-) diff --git a/plugin-gradle/README.md b/plugin-gradle/README.md index f01d015ec7..5ad8c27d42 100644 --- a/plugin-gradle/README.md +++ b/plugin-gradle/README.md @@ -84,6 +84,8 @@ Spotless can check and apply formatting to any plain-text file, using simple rul * [ktlint](https://github.com/shyiko/ktlint) * [scalafmt](https://github.com/olafurpg/scalafmt) * [DBeaver sql format](https://dbeaver.jkiss.org/) +* [Prettier: An opinionated code formatter](https://prettier.io) +* [TypeScript Formatter (tsfmt)](https://github.com/vvakame/typescript-formatter) * Any user-defined function which takes an unformatted string and outputs a formatted version. Contributions are welcome, see [the contributing guide](../CONTRIBUTING.md) for development info. @@ -291,85 +293,177 @@ spotless { } ``` - + -## License header options +## Applying to Typescript source -If the string contents of a licenseHeader step or the file contents of a licenseHeaderFile step contains a $YEAR token, -then in the end-result generated license headers which use this license header as a template, $YEAR will be replaced with the current year. +To use tsfmt, you first have to specify the files that you want it to apply to. +Then you specify `tsfmt()`, and optionally how you want to apply it. +By default, all typescript source sets will be formatted. To change this, +set the `target` parameter as described in the [Custom rules](#custom) section. -For example: -``` -/* Licensed under Apache-2.0 $YEAR. */ -``` -will produce +```gradle +spotless { + typescript { + // using existing config files + tsfmt().configFile(['basedir': '/path/to/repo', 'tslint': true, 'tslintFile', '/path/to/repo/tslint.json']) + } +} ``` -/* Licensed under Apache-2.0 2017. */ +*Please note:* The auto-discovery of config files (up the file tree) will not work when using prettier within spotless, + hence you are required to provide absolute file paths for config files. + +... or alternatively provide the configuration inline ... + +```gradle +spotless { + typescript { + // custom file-set + target 'src/main/resources/**/*.ts' + // provide config inline + tsfmt().config(['indentSize': 1, 'convertTabsToSpaces': true]) + } +} ``` -if Spotless is launched in 2017 +See [tsfmt's default config settings](https://github.com/vvakame/typescript-formatter/blob/7764258ad42ac65071399840d1b8701868510ca7/lib/utils.ts#L8) for what is available. -The `licenseHeader` and `licenseHeaderFile` steps will generate license headers with automatic years from the base license header according to the following rules: -* A generated license header will be updated with the current year when - * the generated license header is missing - * the generated license header is not formatted correctly -* A generated license header will _not_ be updated when - * a single year is already present, e.g. - `/* Licensed under Apache-2.0 1990. */` - * a year range is already present, e.g. - `/* Licensed under Apache-2.0 1990-2003. */` - * the `$YEAR` token is otherwise missing +*Please note:* If both `configFile` and `config` is provided, only `config` is used. -The separator for the year range defaults to the hyphen character, e.g `1990-2003`, but can be customized with the `yearSeparator` property. -For instance, the following configuration treats `1990, 2003` as a valid year range. + +### Prerequisite: tsfmt requires a working NodeJS version + +tsfmt is based on NodeJS, so to use it, a working NodeJS installation (especially npm) is required on the host running spotless. +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. ```gradle spotless { - java { - licenseHeader('Licensed under Apache-2.0 $YEAR').yearSeparator(', ') + typescript { + tsfmt().npmExecutable('/usr/bin/npm').config(...) } } ``` -## Applying [prettier](https://prettier.io/) to javascript | flow | typeScript | css | scss | less | jsx | etc. +## Applying [Prettier](https://prettier.io) to javascript | flow | typeScript | css | scss | less | jsx | graphQL | yaml | etc. + +Prettier is a formatter that can format [multiple file types](https://prettier.io/docs/en/language-support.html). 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. ```gradle spotless { - format 'css', { - target 'src/main/resources/**/*.css' - prettier().prettierConfig([type: 'css']) + format 'styling', { + target '**/*.css', '**/*.scss' + + // at least provide the parser to use + prettier().config(['parser': 'postcss']) + + // or provide a typical filename + prettier().config(['filepath': 'style.scss']) } } ``` +Supported config options are documented on [prettier.io](https://prettier.io/docs/en/options.html). + +It is also possible to specify the config via file: + +```gradle +spotless { + format 'styling', { + target '**/*.css', '**/*.scss' + + // or provide both (config options will win over configFile options) + prettier().configFile('/path-to/.prettierrc.yml') + + // or provide both (config options will win over configFile options) + prettier().config(['parser': 'postcss']).configFile('path-to/.prettierrc.yml') + } +} +``` + +Supported config file variants are documented on [prettier.io](https://prettier.io/docs/en/configuration.html). +Please note: +- The auto-discovery of config files (up the file tree) will not work when using prettier within spotless. +- Prettier's override syntax is not supported when using prettier within spotless. + To apply prettier to more kinds of files, just add more formats ```gradle spotless { format 'javascript', { target 'src/main/resources/**/*.js' - prettier().prettierConfig([type: 'js']) + prettier().config(['filepath': 'file.js']) } } ``` - +Prettier can also be applied from within the [typescript config block](#typescript-formatter): + +```gradle +spotless { + typescript { + // no parser or filepath needed + // -> will default to 'typesript' parser when used in the typescript block + prettier() + } +} +``` -## Applying [tsfmt](https://github.com/vvakame/typescript-formatter) to typescript +### Prerequisite: prettier requires a working NodeJS version -To use tsfmt, you first have to specify the files that you want it to apply to. Then you specify `tsfmt()`, and optionally how you want to apply it. +prettier, like tsfmt, is based on NodeJS, so to use it, a working NodeJS installation (especially npm) is required on the host running spotless. +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. ```gradle spotless { - typescript { - target 'src/main/resources/**/*.ts' - tsfmt().config([type: 'something']) + format 'javascript', { + prettier().npmExecutable('/usr/bin/npm').config(...) + } +} +``` + + +## License header options + +If the string contents of a licenseHeader step or the file contents of a licenseHeaderFile step contains a $YEAR token, +then in the end-result generated license headers which use this license header as a template, $YEAR will be replaced with the current year. + + +For example: +``` +/* Licensed under Apache-2.0 $YEAR. */ +``` +will produce +``` +/* Licensed under Apache-2.0 2017. */ +``` +if Spotless is launched in 2017 + + +The `licenseHeader` and `licenseHeaderFile` steps will generate license headers with automatic years from the base license header according to the following rules: +* A generated license header will be updated with the current year when + * the generated license header is missing + * the generated license header is not formatted correctly +* A generated license header will _not_ be updated when + * a single year is already present, e.g. + `/* Licensed under Apache-2.0 1990. */` + * a year range is already present, e.g. + `/* Licensed under Apache-2.0 1990-2003. */` + * the `$YEAR` token is otherwise missing + +The separator for the year range defaults to the hyphen character, e.g `1990-2003`, but can be customized with the `yearSeparator` property. + +For instance, the following configuration treats `1990, 2003` as a valid year range. + +```gradle +spotless { + java { + licenseHeader('Licensed under Apache-2.0 $YEAR').yearSeparator(', ') } } ``` From 732e27ab45db8b170efceb70f1c1ece4b1acbd53 Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:53:54 +0200 Subject: [PATCH 33/45] unify naming --- .../java/com/diffplug/gradle/spotless/FormatExtension.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java index 7c66dd641d..1a187c118f 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java @@ -458,13 +458,13 @@ public class PrettierConfig extends NpmStepConfig { @Nullable protected Map prettierConfig; - public PrettierConfig prettierConfigFile(final Object prettierConfigFile) { + public PrettierConfig configFile(final Object prettierConfigFile) { this.prettierConfigFile = prettierConfigFile; replaceStep(createStep()); return this; } - public PrettierConfig prettierConfig(final Map prettierConfig) { + public PrettierConfig config(final Map prettierConfig) { this.prettierConfig = prettierConfig; replaceStep(createStep()); return this; From e400fa59c97ea0d485301f9ed4be205a6bae9c9a Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:54:06 +0200 Subject: [PATCH 34/45] provide default basedir --- .../diffplug/gradle/spotless/TypescriptExtension.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java index 23b4b3f044..03040e6019 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java @@ -17,12 +17,15 @@ import java.util.Collections; import java.util.Map; +import java.util.TreeMap; import org.gradle.api.Project; import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.extra.npm.TsFmtFormatterStep; +import static java.util.Objects.requireNonNull; + public class TypescriptExtension extends FormatExtension { static final String NAME = "typescript"; @@ -42,13 +45,17 @@ public class TypescriptFormatExtension extends NpmStepConfig tsFmtConfig = Collections.emptyMap(); public TypescriptFormatExtension config(Map config) { - this.tsFmtConfig = config; + this.tsFmtConfig = new TreeMap<>(requireNonNull(config)); replaceStep(createStep()); return this; } public FormatterStep createStep() { final Project project = getProject(); + Map config = new TreeMap<>(this.tsFmtConfig); + if (!config.containsKey("basedir")) { + config.put("basedir", project.getRootDir().getAbsolutePath()); //by default we use our project dir + } return TsFmtFormatterStep.create( GradleProvisioner.fromProject(project), project.getBuildDir(), From 1fb5838b4f10b15e3a7b5d6dac3367eed51719f0 Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:54:22 +0200 Subject: [PATCH 35/45] step 1 on supporting inline-config for typescript-formatter --- .../spotless/extra/npm/SimpleJsonWriter.java | 88 +++++++++++++++++++ .../extra/npm/SimpleJsonWriterTest.java | 75 ++++++++++++++++ .../gradle/spotless/FormatExtension.java | 9 +- .../gradle/spotless/SpotlessExtension.java | 2 +- .../gradle/spotless/TypescriptExtension.java | 72 +++++++++++++-- 5 files changed, 230 insertions(+), 16 deletions(-) create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/npm/SimpleJsonWriter.java create mode 100644 lib-extra/src/test/java/com/diffplug/spotless/extra/npm/SimpleJsonWriterTest.java diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/SimpleJsonWriter.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/SimpleJsonWriter.java new file mode 100644 index 0000000000..f15b9b4754 --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/SimpleJsonWriter.java @@ -0,0 +1,88 @@ +/* + * 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.extra.npm; + +import static java.util.Objects.requireNonNull; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.stream.Collectors; + +import com.diffplug.common.base.Errors; + +public class SimpleJsonWriter { + + private final LinkedHashMap valueMap = new LinkedHashMap<>(); + + SimpleJsonWriter putAll(Map values) { + verifyValues(values); + this.valueMap.putAll(values); + return this; + } + + SimpleJsonWriter put(String name, Object value) { + verifyValues(Collections.singletonMap(name, value)); + this.valueMap.put(name, value); + return this; + } + + private void verifyValues(Map values) { + if (values.values() + .stream() + .anyMatch(val -> !(val instanceof String || val instanceof Number || val instanceof Boolean))) { + throw new IllegalArgumentException("Only values of type 'String', 'Number' and 'Boolean' are supported. You provided: " + values.values()); + } + } + + String toJsonString() { + final String valueString = valueMap.entrySet() + .stream() + .map(entry -> " " + jsonEscape(entry.getKey()) + ": " + jsonEscape(entry.getValue())) + .collect(Collectors.joining(",\n")); + return "{\n" + valueString + "\n}"; + } + + private String jsonEscape(Object val) { + requireNonNull(val); + if (val instanceof String) { + return "\"" + val + "\""; + } + return val.toString(); + } + + void toJsonFile(File file) { + if (!file.getParentFile().exists()) { + if (!file.getParentFile().mkdirs()) { + throw new RuntimeException("Cannot write to file"); + } + } + try { + Files.write(file.toPath(), toJsonString().getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + throw Errors.asRuntime(e); + } + } + + @Override + public String toString() { + return this.toJsonString(); + } +} diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/SimpleJsonWriterTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/SimpleJsonWriterTest.java new file mode 100644 index 0000000000..69e13e2531 --- /dev/null +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/SimpleJsonWriterTest.java @@ -0,0 +1,75 @@ +/* + * 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.extra.npm; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.*; + +import java.io.File; +import java.io.IOException; + +import org.junit.Test; + +import com.diffplug.common.collect.ImmutableMap; +import com.diffplug.spotless.ResourceHarness; + +public class SimpleJsonWriterTest extends ResourceHarness { + + private SimpleJsonWriter jsonWriter = new SimpleJsonWriter(); + + @Test + public void itWritesAValidEmptyObject() { + assertThat(jsonWriter.toJsonString().replaceAll("\\s", ""), equalTo("{}")); + } + + @Test + public void itWritesABooleanProperty() { + jsonWriter.put("mybool", true); + assertThat(jsonWriter.toJsonString(), equalTo("{\n \"mybool\": true\n}")); + } + + @Test + public void itWritesAStringProperty() { + jsonWriter.put("mystring", "stringvalue"); + assertThat(jsonWriter.toJsonString(), equalTo("{\n \"mystring\": \"stringvalue\"\n}")); + } + + @Test + public void itWritesAnInteger() { + jsonWriter.put("myint", 7); + assertThat(jsonWriter.toJsonString(), equalTo("{\n \"myint\": 7\n}")); + } + + @Test(expected = IllegalArgumentException.class) + public void itFailsOnUnsupportedObject() { + jsonWriter.put("anyobj", new Object()); + fail("should not be accepted"); + } + + @Test + public void itHandlesSeveralOptionsSimultaneously() { + jsonWriter.putAll(ImmutableMap.of("mystring", "stringvalue", "intvalue", 1)); + assertThat(jsonWriter.toJsonString(), equalTo("{\n \"mystring\": \"stringvalue\",\n \"intvalue\": 1\n}")); + } + + @Test + public void itWritesToFile() throws IOException { + jsonWriter.put("mystring", "stringvalue"); + final File file = newFile("target.json"); + jsonWriter.toJsonFile(file); + assertFile(file).hasContent("{\n \"mystring\": \"stringvalue\"\n}"); + } +} diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java index 1a187c118f..1ab9bad52f 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java @@ -20,12 +20,7 @@ import java.io.File; import java.io.Serializable; import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Random; +import java.util.*; import java.util.stream.Stream; import javax.annotation.Nullable; @@ -465,7 +460,7 @@ public PrettierConfig configFile(final Object prettierConfigFile) { } public PrettierConfig config(final Map prettierConfig) { - this.prettierConfig = prettierConfig; + this.prettierConfig = new TreeMap<>(prettierConfig); replaceStep(createStep()); return this; } diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java index 686989b764..8864eafae7 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java @@ -118,7 +118,7 @@ public void sql(Action closure) { configure(SqlExtension.NAME, SqlExtension.class, closure); } - /** Configures the special typescript-specific extension for SQL files. */ + /** Configures the special typescript-specific extension for typescript files. */ public void typescript(Action closure) { configure(TypescriptExtension.NAME, TypescriptExtension.class, closure); } diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java index 03040e6019..523e9c62c2 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java @@ -15,17 +15,24 @@ */ package com.diffplug.gradle.spotless; +import static java.util.Objects.requireNonNull; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.Map; import java.util.TreeMap; +import java.util.stream.Collectors; import org.gradle.api.Project; +import com.diffplug.common.base.Errors; +import com.diffplug.common.base.Strings; +import com.diffplug.common.io.Files; import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.extra.npm.TsFmtFormatterStep; -import static java.util.Objects.requireNonNull; - public class TypescriptExtension extends FormatExtension { static final String NAME = "typescript"; @@ -42,26 +49,75 @@ public TypescriptFormatExtension tsfmt() { public class TypescriptFormatExtension extends NpmStepConfig { - protected Map tsFmtConfig = Collections.emptyMap(); + protected Map config = Collections.emptyMap(); + + protected String configFileType = null; + + protected String configFilePath = null; public TypescriptFormatExtension config(Map config) { - this.tsFmtConfig = new TreeMap<>(requireNonNull(config)); + this.config = new TreeMap<>(requireNonNull(config)); + replaceStep(createStep()); + return this; + } + + public TypescriptFormatExtension configFile(String filetype, String path) { + this.configFileType = requireNonNull(filetype); + this.configFilePath = requireNonNull(path); replaceStep(createStep()); return this; } public FormatterStep createStep() { final Project project = getProject(); - Map config = new TreeMap<>(this.tsFmtConfig); - if (!config.containsKey("basedir")) { - config.put("basedir", project.getRootDir().getAbsolutePath()); //by default we use our project dir - } + + Map tsFmtConfig = createTsFmtConfig(); + return TsFmtFormatterStep.create( GradleProvisioner.fromProject(project), project.getBuildDir(), npmFileOrNull(), tsFmtConfig); } + + private Map createTsFmtConfig() { + final Project project = getProject(); + Map tsFmtConfig = new TreeMap<>(); + if (!this.config.isEmpty()) { + // write it to temporary file + String formatConfig = toJsonString(this.config); + File targetFile = new File(project.getBuildDir(), "tsfmt.json"); + try { + Files.write(formatConfig, targetFile, StandardCharsets.UTF_8); + } catch (IOException e) { + throw Errors.asRuntime(e); + } + tsFmtConfig.put("tsfmt", true); + tsFmtConfig.put("tsfmtFile", targetFile); + } else if (!Strings.isNullOrEmpty(this.configFileType) && !Strings.isNullOrEmpty(this.configFilePath)) { + tsFmtConfig.put(this.configFileType, Boolean.TRUE); + tsFmtConfig.put(this.configFileType + "File", this.configFilePath); + } + tsFmtConfig.put("basedir", getProject().getRootDir().getAbsolutePath()); //by default we use our project dir + return tsFmtConfig; + } + } + + private String toJsonString(Map map) { + final String valueString = map.entrySet() + .stream() + .map(entry -> " " + jsonEscape(entry.getKey()) + ": " + jsonEscape(entry.getValue())) + .collect(Collectors.joining(",\n")); + + return "{\n" + valueString + "\n}"; + } + + private String jsonEscape(Object val) { + requireNonNull(val); + if (val instanceof String) { + return "\"" + val + "\""; + } + return val.toString(); // numbers, booleans - currently nothing else } @Override From b5e57e703e81fb316c0e12aa8e87d36e745af5cd Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:54:37 +0200 Subject: [PATCH 36/45] introduce inline-config for tsfmt step --- .../spotless/extra/npm/SimpleJsonWriter.java | 6 +++ .../extra/npm/TsFmtFormatterStep.java | 47 +++++++++++++++---- .../extra/npm/TsFmtFormatterStepTest.java | 29 +++++++++++- .../gradle/spotless/TypescriptExtension.java | 26 ++-------- 4 files changed, 75 insertions(+), 33 deletions(-) diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/SimpleJsonWriter.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/SimpleJsonWriter.java index f15b9b4754..9f786cf484 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/SimpleJsonWriter.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/SimpleJsonWriter.java @@ -32,6 +32,12 @@ public class SimpleJsonWriter { private final LinkedHashMap valueMap = new LinkedHashMap<>(); + public static SimpleJsonWriter of(Map values) { + SimpleJsonWriter writer = new SimpleJsonWriter(); + writer.putAll(values); + return writer; + } + SimpleJsonWriter putAll(Map values) { verifyValues(values); this.valueMap.putAll(values); diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java index 5f9a4830d1..a9d93dfdb5 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java @@ -21,10 +21,7 @@ import java.io.File; import java.io.IOException; import java.io.Serializable; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.TreeSet; +import java.util.*; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -38,12 +35,13 @@ public class TsFmtFormatterStep { public static final String NAME = "tsfmt-format"; - public static FormatterStep create(Provisioner provisioner, File buildDir, @Nullable File npm, Map tsFmtOptions) { + public static FormatterStep create(Provisioner provisioner, File buildDir, @Nullable File npm, Map tsFmtCliOptions, Map inlineTsFmtSettings) { requireNonNull(provisioner); requireNonNull(buildDir); - validateOptions(requireNonNull(tsFmtOptions)); + validateOptions(requireNonNull(tsFmtCliOptions)); + requireNonNull(inlineTsFmtSettings); return FormatterStep.createLazy(NAME, - () -> new State(NAME, provisioner, buildDir, npm, tsFmtOptions), + () -> new State(NAME, provisioner, buildDir, npm, tsFmtCliOptions, inlineTsFmtSettings), State::createFormatterFunc); } @@ -60,9 +58,13 @@ public static class State extends NpmFormatterStepStateBase implements Serializa private static final long serialVersionUID = -3811104513825329168L; - private final TreeMap tsFmtOptions; + private final TreeMap tsFmtCliOptions; - public State(String stepName, Provisioner provisioner, File buildDir, @Nullable File npm, Map tsFmtOptions) throws IOException { + private final TreeMap inlineTsFmtSettings; + + private final File buildDir; + + public State(String stepName, Provisioner provisioner, File buildDir, @Nullable File npm, Map tsFmtCliOptions, Map inlineTsFmtSettings) throws IOException { super(stepName, provisioner, new NpmConfig( @@ -70,13 +72,17 @@ public State(String stepName, Provisioner provisioner, File buildDir, @Nullable "typescript-formatter"), buildDir, npm); - this.tsFmtOptions = new TreeMap<>(tsFmtOptions); + this.buildDir = buildDir; + this.tsFmtCliOptions = new TreeMap<>(tsFmtCliOptions); + this.inlineTsFmtSettings = new TreeMap<>(inlineTsFmtSettings); } @Override @Nonnull public FormatterFunc createFormatterFunc() { + Map tsFmtOptions = unifyOptions(); + final NodeJSWrapper nodeJSWrapper = nodeJSWrapper(); final V8ObjectWrapper tsFmt = nodeJSWrapper.require(nodeModulePath()); final V8ObjectWrapper formatterOptions = nodeJSWrapper.createNewObject(tsFmtOptions); @@ -135,5 +141,26 @@ public FormatterFunc createFormatterFunc() { }); } + private Map unifyOptions() { + Map unified = new HashMap<>(this.tsFmtCliOptions); + + if (!this.inlineTsFmtSettings.isEmpty()) { + removeAllConfigFileSettings(unified); + File targetFile = new File(this.buildDir, "inline-tsfmt.json"); + SimpleJsonWriter.of(this.inlineTsFmtSettings).toJsonFile(targetFile); + unified.put("tsfmt", true); + unified.put("tsfmtFile", targetFile.getAbsolutePath()); + } + return unified; + } + + private void removeAllConfigFileSettings(Map settings) { + Arrays.asList("tsconfig", "tslint", "editorconfig", "vscode", "tsfmt").forEach( + format -> { + settings.remove(format); + settings.remove(format + "File"); + }); + } + } } diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java index 7ecb7179e8..50dad615e7 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java @@ -21,6 +21,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.Arrays; +import java.util.Collections; import org.junit.Test; import org.junit.experimental.categories.Category; @@ -67,7 +68,8 @@ ImmutableMap. builder() .put("basedir", configFile.getParent()) .put(configFileNameWithoutExtension, Boolean.TRUE) .put(configFileNameWithoutExtension + "File", configFile.getPath()) - .build()); + .build(), + Collections.emptyMap()); try (StepHarness stepHarness = StepHarness.forStep(formatterStep)) { stepHarness.testResource(dirtyFile, cleanFile); @@ -75,6 +77,28 @@ ImmutableMap. builder() } } + @Category(NpmTest.class) + public static class TsFmtUsingInlineConfigTest extends NpmFormatterStepCommonTests { + @Test + public void formattingUsingInlineConfigWorks() throws Exception { + + final ImmutableMap inlineConfig = ImmutableMap.of("indentSize", 1, "convertTabsToSpaces", true); + + final FormatterStep formatterStep = TsFmtFormatterStep.create( + TestProvisioner.mavenCentral(), + buildDir(), + npmExecutable(), + ImmutableMap. builder() + .put("basedir", buildDir().getAbsolutePath()) + .build(), + inlineConfig); + + try (StepHarness stepHarness = StepHarness.forStep(formatterStep)) { + stepHarness.testResource("npm/tsfmt/tsfmt/tsfmt.dirty", "npm/tsfmt/tsfmt/tsfmt.clean"); + } + } + } + @Category(NpmTest.class) @RunWith(Parameterized.class) public static class TsFmtBlacklistedOptionsTest extends NpmFormatterStepCommonTests { @@ -94,7 +118,8 @@ public void blacklistedOptionIsThrown() throws Exception { npmExecutable(), ImmutableMap. builder() .put(blackListedOption, Boolean.TRUE) - .build()); + .build(), + Collections.emptyMap()); fail("should never be reached!"); diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java index 523e9c62c2..8dba1cb762 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java @@ -17,9 +17,6 @@ import static java.util.Objects.requireNonNull; -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.Map; import java.util.TreeMap; @@ -27,9 +24,7 @@ import org.gradle.api.Project; -import com.diffplug.common.base.Errors; import com.diffplug.common.base.Strings; -import com.diffplug.common.io.Files; import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.extra.npm.TsFmtFormatterStep; @@ -71,30 +66,19 @@ public TypescriptFormatExtension configFile(String filetype, String path) { public FormatterStep createStep() { final Project project = getProject(); - Map tsFmtConfig = createTsFmtConfig(); + Map tsFmtCliOptions = craeateTsFmtCliOptions(); return TsFmtFormatterStep.create( GradleProvisioner.fromProject(project), project.getBuildDir(), npmFileOrNull(), - tsFmtConfig); + tsFmtCliOptions, + config); } - private Map createTsFmtConfig() { - final Project project = getProject(); + private Map craeateTsFmtCliOptions() { Map tsFmtConfig = new TreeMap<>(); - if (!this.config.isEmpty()) { - // write it to temporary file - String formatConfig = toJsonString(this.config); - File targetFile = new File(project.getBuildDir(), "tsfmt.json"); - try { - Files.write(formatConfig, targetFile, StandardCharsets.UTF_8); - } catch (IOException e) { - throw Errors.asRuntime(e); - } - tsFmtConfig.put("tsfmt", true); - tsFmtConfig.put("tsfmtFile", targetFile); - } else if (!Strings.isNullOrEmpty(this.configFileType) && !Strings.isNullOrEmpty(this.configFilePath)) { + if (!Strings.isNullOrEmpty(this.configFileType) && !Strings.isNullOrEmpty(this.configFilePath)) { tsFmtConfig.put(this.configFileType, Boolean.TRUE); tsFmtConfig.put(this.configFileType + "File", this.configFilePath); } From 2a21254080c391058cf86d043ebb2d005e61f92d Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:54:54 +0200 Subject: [PATCH 37/45] adding more integration tests for typescript extension --- .../spotless/TypescriptExtensionTest.java | 46 ++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java index dcd280a6a0..e599b8fc8f 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java @@ -15,6 +15,7 @@ */ package com.diffplug.gradle.spotless; +import java.io.File; import java.io.IOException; import org.junit.Test; @@ -23,7 +24,7 @@ @Category(NpmTest.class) public class TypescriptExtensionTest extends GradleIntegrationTest { @Test - public void integration() throws IOException { + public void useTsfmtInlineConfig() throws IOException { setFile("build.gradle").toLines( "buildscript { repositories { mavenCentral() } }", "plugins {", @@ -39,7 +40,48 @@ public void integration() throws IOException { " }", "}"); setFile("test.ts").toResource("npm/tsfmt/tsfmt/tsfmt.dirty"); - gradleRunner().withArguments("spotlessApply").build(); + gradleRunner().withArguments("--stacktrace", "spotlessApply").build(); assertFile("test.ts").sameAsResource("npm/tsfmt/tsfmt/tsfmt.clean"); } + + @Test + public void useTsfmtFileConfig() throws IOException { + File formattingFile = setFile("tsfmt.json").toLines( + "{", + " \"indentSize\": 1,", + " \"convertTabsToSpaces\": true", + "}"); + setFile("build.gradle").toLines( + "buildscript { repositories { mavenCentral() } }", + "plugins {", + " id 'com.diffplug.gradle.spotless'", + "}", + "spotless {", + " typescript {", + " target 'test.ts'", + " tsfmt().configFile('tsfmt', '" + formattingFile.getAbsolutePath() + "')", + " }", + "}"); + setFile("test.ts").toResource("npm/tsfmt/tsfmt/tsfmt.dirty"); + gradleRunner().withArguments("--stacktrace", "spotlessApply").build(); + assertFile("test.ts").sameAsResource("npm/tsfmt/tsfmt/tsfmt.clean"); + } + + @Test + public void usePrettier() throws IOException { + setFile("build.gradle").toLines( + "buildscript { repositories { mavenCentral() } }", + "plugins {", + " id 'com.diffplug.gradle.spotless'", + "}", + "spotless {", + " typescript {", + " target 'test.ts'", + " prettier()", + " }", + "}"); + setFile("test.ts").toResource("npm/prettier/filetypes/typescript/typescript.dirty"); + gradleRunner().withArguments("--stacktrace", "spotlessApply").build(); + assertFile("test.ts").sameAsResource("npm/prettier/filetypes/typescript/typescript.clean"); + } } From 3af839f93a74c52bded7b93147950c36d268eef0 Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:55:09 +0200 Subject: [PATCH 38/45] integration tests for prettier formatter --- .../spotless/PrettierIntegrationTest.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 plugin-gradle/src/test/java/com/diffplug/gradle/spotless/PrettierIntegrationTest.java diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/PrettierIntegrationTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/PrettierIntegrationTest.java new file mode 100644 index 0000000000..a36203be6e --- /dev/null +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/PrettierIntegrationTest.java @@ -0,0 +1,66 @@ +/* + * 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.gradle.spotless; + +import java.io.File; +import java.io.IOException; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(NpmTest.class) +public class PrettierIntegrationTest extends GradleIntegrationTest { + @Test + public void useInlineConfig() throws IOException { + setFile("build.gradle").toLines( + "buildscript { repositories { mavenCentral() } }", + "plugins {", + " id 'com.diffplug.gradle.spotless'", + "}", + "def prettierConfig = [:]", + "prettierConfig['printWidth'] = 50", + "prettierConfig['parser'] = 'typescript'", + "spotless {", + " format 'mytypescript', {", + " target 'test.ts'", + " prettier().config(prettierConfig)", + " }", + "}"); + setFile("test.ts").toResource("npm/prettier/config/typescript.dirty"); + gradleRunner().withArguments("--stacktrace", "spotlessApply").build(); + assertFile("test.ts").sameAsResource("npm/prettier/config/typescript.configfile.clean"); + } + + @Test + public void useFileConfig() throws IOException { + File formattingFile = setFile(".prettierrc.yml").toResource("npm/prettier/config/.prettierrc.yml"); + setFile("build.gradle").toLines( + "buildscript { repositories { mavenCentral() } }", + "plugins {", + " id 'com.diffplug.gradle.spotless'", + "}", + "spotless {", + " format 'mytypescript', {", + " target 'test.ts'", + " prettier().configFile('" + formattingFile.getAbsolutePath() + "')", + " }", + "}"); + setFile("test.ts").toResource("npm/prettier/config/typescript.dirty"); + gradleRunner().withArguments("--stacktrace", "spotlessApply").build(); + assertFile("test.ts").sameAsResource("npm/prettier/config/typescript.configfile.clean"); + } + +} From c3c8ae1e74a851beb1db404577e92f7135b4d9db Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Fri, 7 Sep 2018 08:55:29 +0200 Subject: [PATCH 39/45] unify usage of NpmTest category since it was duplicated and because of that not correctly referenced in build --- lib-extra/build.gradle | 4 ++-- .../diffplug/spotless/extra/npm/NpmTest.java | 20 ------------------- .../extra/npm/PrettierFormatterStepTest.java | 1 + .../extra/npm/TsFmtFormatterStepTest.java | 1 + plugin-gradle/build.gradle | 4 ++-- .../spotless/PrettierIntegrationTest.java | 2 ++ .../spotless/TypescriptExtensionTest.java | 2 ++ .../diffplug/spotless/category}/NpmTest.java | 6 ++---- 8 files changed, 12 insertions(+), 28 deletions(-) delete mode 100644 lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmTest.java rename {plugin-gradle/src/test/java/com/diffplug/gradle/spotless => testlib/src/main/java/com/diffplug/spotless/category}/NpmTest.java (89%) diff --git a/lib-extra/build.gradle b/lib-extra/build.gradle index 1a4b48ac61..95eef4046c 100644 --- a/lib-extra/build.gradle +++ b/lib-extra/build.gradle @@ -24,6 +24,6 @@ dependencies { // we'll hold the core lib to a high standard spotbugs { reportLevel = 'low' } // low|medium|high (low = sensitive to even minor mistakes) -test { useJUnit { excludeCategories 'com.diffplug.spotless.extra.npm.NpmTest' } } +test { useJUnit { excludeCategories 'com.diffplug.spotless.category.NpmTest' } } -task npmTest(type: Test) { useJUnit { includeCategories 'com.diffplug.spotless.extra.npm.NpmTest' } } +task npmTest(type: Test) { useJUnit { includeCategories 'com.diffplug.spotless.category.NpmTest' } } diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmTest.java deleted file mode 100644 index 0575b0f04a..0000000000 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmTest.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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.extra.npm; - -public interface NpmTest { - -} diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java index 43636563d4..0f9440ac3b 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java @@ -26,6 +26,7 @@ import com.diffplug.common.collect.ImmutableMap; import com.diffplug.spotless.*; +import com.diffplug.spotless.category.NpmTest; @Category(NpmTest.class) @RunWith(Enclosed.class) diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java index 50dad615e7..5949e76292 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java @@ -31,6 +31,7 @@ import com.diffplug.common.collect.ImmutableMap; import com.diffplug.spotless.*; +import com.diffplug.spotless.category.NpmTest; @Category(NpmTest.class) @RunWith(Enclosed.class) diff --git a/plugin-gradle/build.gradle b/plugin-gradle/build.gradle index eb405d7b27..1f94ecda91 100644 --- a/plugin-gradle/build.gradle +++ b/plugin-gradle/build.gradle @@ -41,9 +41,9 @@ task spotlessApply(type: JavaExec) { } test { testLogging.showStandardStreams = true } -test { useJUnit { excludeCategories 'com.diffplug.spotless.extra.npm.NpmTest' } } +test { useJUnit { excludeCategories 'com.diffplug.spotless.category.NpmTest' } } -task npmTest(type: Test) { useJUnit { includeCategories 'com.diffplug.gradle.spotless.NpmTest' } } +task npmTest(type: Test) { useJUnit { includeCategories 'com.diffplug.spotless.category.NpmTest' } } ////////////////////////// // GRADLE PLUGIN PORTAL // diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/PrettierIntegrationTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/PrettierIntegrationTest.java index a36203be6e..f850225878 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/PrettierIntegrationTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/PrettierIntegrationTest.java @@ -21,6 +21,8 @@ import org.junit.Test; import org.junit.experimental.categories.Category; +import com.diffplug.spotless.category.NpmTest; + @Category(NpmTest.class) public class PrettierIntegrationTest extends GradleIntegrationTest { @Test diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java index e599b8fc8f..de884dede1 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java @@ -21,6 +21,8 @@ import org.junit.Test; import org.junit.experimental.categories.Category; +import com.diffplug.spotless.category.NpmTest; + @Category(NpmTest.class) public class TypescriptExtensionTest extends GradleIntegrationTest { @Test diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/NpmTest.java b/testlib/src/main/java/com/diffplug/spotless/category/NpmTest.java similarity index 89% rename from plugin-gradle/src/test/java/com/diffplug/gradle/spotless/NpmTest.java rename to testlib/src/main/java/com/diffplug/spotless/category/NpmTest.java index a2bc84b43c..c04c6199bf 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/NpmTest.java +++ b/testlib/src/main/java/com/diffplug/spotless/category/NpmTest.java @@ -13,8 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.gradle.spotless; +package com.diffplug.spotless.category; -public interface NpmTest { - -} +public interface NpmTest {} From f8173099bfd80c811d115371ca474b3fa14373e7 Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Sat, 8 Sep 2018 18:09:46 +0200 Subject: [PATCH 40/45] PR feedback: extract into sub-methods in order to make the code more readable --- .../extra/npm/PrettierFormatterStep.java | 74 +++++++++++-------- .../extra/npm/TsFmtFormatterStep.java | 20 +++-- 2 files changed, 57 insertions(+), 37 deletions(-) diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java index 153bc7e229..4aaa23cd08 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java @@ -70,42 +70,19 @@ public FormatterFunc createFormatterFunc() { @SuppressWarnings("unchecked") final Map[] resolvedPrettierOptions = (Map[]) new Map[1]; + if (this.prettierConfig.getPrettierConfigPath() != null) { final Exception[] toThrow = new Exception[1]; try ( - V8FunctionWrapper resolveConfigCallback = nodeJSWrapper.createNewFunction((receiver, parameters) -> { - try { - try (final V8ObjectWrapper configOptions = parameters.getObject(0)) { - if (configOptions == null) { - toThrow[0] = new IllegalArgumentException("Cannot find or read config file " + this.prettierConfig.getPrettierConfigPath()); - } else { - Map resolvedOptions = new TreeMap<>(V8ObjectUtilsWrapper.toMap(configOptions)); - resolvedOptions.putAll(this.prettierConfig.getOptions()); - resolvedPrettierOptions[0] = resolvedOptions; - } - } - } catch (Exception e) { - toThrow[0] = e; - } - return receiver; - }); - V8ObjectWrapper resolveConfigOption = nodeJSWrapper.createNewObject() - .add("config", this.prettierConfig.getPrettierConfigPath().getAbsolutePath()); - V8ArrayWrapper resolveConfigParams = nodeJSWrapper.createNewArray() - .pushNull() - .push(resolveConfigOption); + V8FunctionWrapper resolveConfigCallback = createResolveConfigFunction(nodeJSWrapper, resolvedPrettierOptions, toThrow); + V8ObjectWrapper resolveConfigOption = createResolveConfigOptionObj(nodeJSWrapper); + V8ArrayWrapper resolveConfigParams = createResolveConfigParamsArray(nodeJSWrapper, resolveConfigOption); + V8ObjectWrapper promise = prettier.executeObjectFunction("resolveConfig", resolveConfigParams); V8ArrayWrapper callbacks = nodeJSWrapper.createNewArray(resolveConfigCallback);) { promise.executeVoidFunction("then", callbacks); - - while (resolvedPrettierOptions[0] == null && toThrow[0] == null) { - nodeJSWrapper.handleMessage(); - } - - if (toThrow[0] != null) { - throw ThrowingEx.asRuntime(toThrow[0]); - } + executeResolution(nodeJSWrapper, resolvedPrettierOptions, toThrow); } } else { resolvedPrettierOptions[0] = this.prettierConfig.getOptions(); @@ -124,7 +101,46 @@ public FormatterFunc createFormatterFunc() { } catch (Exception e) { throw ThrowingEx.asRuntime(e); } + } + private V8FunctionWrapper createResolveConfigFunction(NodeJSWrapper nodeJSWrapper, Map[] outputOptions, Exception[] toThrow) { + return nodeJSWrapper.createNewFunction((receiver, parameters) -> { + try { + try (final V8ObjectWrapper configOptions = parameters.getObject(0)) { + if (configOptions == null) { + toThrow[0] = new IllegalArgumentException("Cannot find or read config file " + this.prettierConfig.getPrettierConfigPath()); + } else { + Map resolvedOptions = new TreeMap<>(V8ObjectUtilsWrapper.toMap(configOptions)); + resolvedOptions.putAll(this.prettierConfig.getOptions()); + outputOptions[0] = resolvedOptions; + } + } + } catch (Exception e) { + toThrow[0] = e; + } + return receiver; + }); + } + + private V8ObjectWrapper createResolveConfigOptionObj(NodeJSWrapper nodeJSWrapper) { + return nodeJSWrapper.createNewObject() + .add("config", this.prettierConfig.getPrettierConfigPath().getAbsolutePath()); + } + + private V8ArrayWrapper createResolveConfigParamsArray(NodeJSWrapper nodeJSWrapper, V8ObjectWrapper resolveConfigOption) { + return nodeJSWrapper.createNewArray() + .pushNull() + .push(resolveConfigOption); + } + + private void executeResolution(NodeJSWrapper nodeJSWrapper, Map[] resolvedPrettierOptions, Exception[] toThrow) { + while (resolvedPrettierOptions[0] == null && toThrow[0] == null) { + nodeJSWrapper.handleMessage(); + } + + if (toThrow[0] != null) { + throw ThrowingEx.asRuntime(toThrow[0]); + } } } diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java index a9d93dfdb5..79c0c4a1db 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java @@ -90,14 +90,7 @@ public FormatterFunc createFormatterFunc() { final TsFmtResult[] tsFmtResult = new TsFmtResult[1]; final Exception[] toThrow = new Exception[1]; - V8FunctionWrapper formatResultCallback = nodeJSWrapper.createNewFunction((receiver, parameters) -> { - try (final V8ObjectWrapper result = parameters.getObject(0)) { - tsFmtResult[0] = new TsFmtResult(result.getString("message"), result.getBoolean("error"), result.getString("dest")); - } catch (Exception e) { - toThrow[0] = e; - } - return receiver; - }); + V8FunctionWrapper formatResultCallback = createFormatResultCallback(nodeJSWrapper, tsFmtResult, toThrow); /* var result = { fileName: fileName, @@ -141,6 +134,17 @@ public FormatterFunc createFormatterFunc() { }); } + private V8FunctionWrapper createFormatResultCallback(NodeJSWrapper nodeJSWrapper, TsFmtResult[] outputTsFmtResult, Exception[] toThrow) { + return nodeJSWrapper.createNewFunction((receiver, parameters) -> { + try (final V8ObjectWrapper result = parameters.getObject(0)) { + outputTsFmtResult[0] = new TsFmtResult(result.getString("message"), result.getBoolean("error"), result.getString("dest")); + } catch (Exception e) { + toThrow[0] = e; + } + return receiver; + }); + } + private Map unifyOptions() { Map unified = new HashMap<>(this.tsFmtCliOptions); From bf16cabcdec1e6838e60ef00bb3ef6fe7af0ac67 Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Sun, 9 Sep 2018 13:16:27 +0200 Subject: [PATCH 41/45] update documentation for tsfmt config file part and fix implementation to handle special case `editorconfig`. --- plugin-gradle/README.md | 12 +++++++++--- .../gradle/spotless/TypescriptExtension.java | 12 +++++++----- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/plugin-gradle/README.md b/plugin-gradle/README.md index 5ad8c27d42..6dc3969250 100644 --- a/plugin-gradle/README.md +++ b/plugin-gradle/README.md @@ -307,12 +307,18 @@ set the `target` parameter as described in the [Custom rules](#custom) section. spotless { typescript { // using existing config files - tsfmt().configFile(['basedir': '/path/to/repo', 'tslint': true, 'tslintFile', '/path/to/repo/tslint.json']) + tsfmt().configFile('tslint', '/path/to/repo/tslint.json') } } ``` -*Please note:* The auto-discovery of config files (up the file tree) will not work when using prettier within spotless, +Supported config file types are the ones supported by [tsfmt config options](https://github.com/vvakame/typescript-formatter/blob/7764258ad42ac65071399840d1b8701868510ca7/lib/index.ts#L26). +Use the option names of type boolean in the tsfmt config object: `tsconfig`, `tslint`, `editorconfig`, `vscode` or `tsfmt`. For the option `editorconfig`, no path is supported. + +*Please note:* +- The auto-discovery of config files (up the file tree) will not work when using prettier within spotless, hence you are required to provide absolute file paths for config files. +- The config file type `editorconfig` is only read from its default location (the user'home). + Any value you pass for the path will be ignored. ... or alternatively provide the configuration inline ... @@ -387,7 +393,7 @@ spotless { ``` Supported config file variants are documented on [prettier.io](https://prettier.io/docs/en/configuration.html). -Please note: +*Please note:* - The auto-discovery of config files (up the file tree) will not work when using prettier within spotless. - Prettier's override syntax is not supported when using prettier within spotless. diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java index 8dba1cb762..b3f63b46d2 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java @@ -58,7 +58,7 @@ public TypescriptFormatExtension config(Map config) { public TypescriptFormatExtension configFile(String filetype, String path) { this.configFileType = requireNonNull(filetype); - this.configFilePath = requireNonNull(path); + this.configFilePath = path; // might be null for 'editorconfig' replaceStep(createStep()); return this; } @@ -66,7 +66,7 @@ public TypescriptFormatExtension configFile(String filetype, String path) { public FormatterStep createStep() { final Project project = getProject(); - Map tsFmtCliOptions = craeateTsFmtCliOptions(); + Map tsFmtCliOptions = createTsFmtCliOptions(); return TsFmtFormatterStep.create( GradleProvisioner.fromProject(project), @@ -76,11 +76,13 @@ public FormatterStep createStep() { config); } - private Map craeateTsFmtCliOptions() { + private Map createTsFmtCliOptions() { Map tsFmtConfig = new TreeMap<>(); - if (!Strings.isNullOrEmpty(this.configFileType) && !Strings.isNullOrEmpty(this.configFilePath)) { + if (!Strings.isNullOrEmpty(this.configFileType)) { tsFmtConfig.put(this.configFileType, Boolean.TRUE); - tsFmtConfig.put(this.configFileType + "File", this.configFilePath); + if (!Strings.isNullOrEmpty(this.configFilePath) && !this.configFileType.equals("editorconfig")) { + tsFmtConfig.put(this.configFileType + "File", this.configFilePath); + } } tsFmtConfig.put("basedir", getProject().getRootDir().getAbsolutePath()); //by default we use our project dir return tsFmtConfig; From 3d3f304b10399343e90c2c87cfa79024e3faf263 Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Tue, 11 Sep 2018 20:22:35 +0200 Subject: [PATCH 42/45] smaller api for tsfmt config files and represent config file content in TsFmtFormatterStep's state --- .../spotless/extra/npm/TsConfigFileType.java | 29 +++++++ .../extra/npm/TsFmtFormatterStep.java | 48 +++++------- .../extra/npm/TypedTsFmtConfigFile.java | 76 +++++++++++++++++++ .../extra/npm/TsFmtFormatterStepTest.java | 43 +---------- plugin-gradle/README.md | 19 ++--- .../gradle/spotless/TypescriptExtension.java | 73 +++++++++--------- .../spotless/TypescriptExtensionTest.java | 6 +- 7 files changed, 171 insertions(+), 123 deletions(-) create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsConfigFileType.java create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TypedTsFmtConfigFile.java diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsConfigFileType.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsConfigFileType.java new file mode 100644 index 0000000000..5e118ad81e --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsConfigFileType.java @@ -0,0 +1,29 @@ +/* + * 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.extra.npm; + +import java.util.Arrays; + +public enum TsConfigFileType { + TSCONFIG, TSLINT, VSCODE, TSFMT; + + public static TsConfigFileType forNameIgnoreCase(String name) { + return Arrays.stream(values()) + .filter(type -> type.name().equalsIgnoreCase(name)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("Config file type " + name + " is not supported. Supported values (case is ignored): " + Arrays.toString(values()))); + } +} diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java index 79c0c4a1db..320c638b08 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java @@ -35,36 +35,29 @@ public class TsFmtFormatterStep { public static final String NAME = "tsfmt-format"; - public static FormatterStep create(Provisioner provisioner, File buildDir, @Nullable File npm, Map tsFmtCliOptions, Map inlineTsFmtSettings) { + public static FormatterStep create(Provisioner provisioner, File buildDir, @Nullable File npm, File baseDir, @Nullable TypedTsFmtConfigFile configFile, @Nullable Map inlineTsFmtSettings) { requireNonNull(provisioner); requireNonNull(buildDir); - validateOptions(requireNonNull(tsFmtCliOptions)); - requireNonNull(inlineTsFmtSettings); + requireNonNull(baseDir); return FormatterStep.createLazy(NAME, - () -> new State(NAME, provisioner, buildDir, npm, tsFmtCliOptions, inlineTsFmtSettings), + () -> new State(NAME, provisioner, buildDir, npm, baseDir, configFile, inlineTsFmtSettings), State::createFormatterFunc); } - private static void validateOptions(Map options) { - final Set optionNames = new TreeSet<>(options.keySet()); - optionNames.retainAll(asList("dryRun", "replace", "verify")); - - if (!optionNames.isEmpty()) { - throw new BlacklistedOptionException("The following config options are specified but not supported by spotless: " + optionNames); - } - } - public static class State extends NpmFormatterStepStateBase implements Serializable { private static final long serialVersionUID = -3811104513825329168L; - private final TreeMap tsFmtCliOptions; - private final TreeMap inlineTsFmtSettings; private final File buildDir; - public State(String stepName, Provisioner provisioner, File buildDir, @Nullable File npm, Map tsFmtCliOptions, Map inlineTsFmtSettings) throws IOException { + @Nullable + private final TypedTsFmtConfigFile configFile; + + private final File baseDir; + + public State(String stepName, Provisioner provisioner, File buildDir, @Nullable File npm, File baseDir, @Nullable TypedTsFmtConfigFile configFile, @Nullable Map inlineTsFmtSettings) throws IOException { super(stepName, provisioner, new NpmConfig( @@ -72,9 +65,10 @@ public State(String stepName, Provisioner provisioner, File buildDir, @Nullable "typescript-formatter"), buildDir, npm); - this.buildDir = buildDir; - this.tsFmtCliOptions = new TreeMap<>(tsFmtCliOptions); - this.inlineTsFmtSettings = new TreeMap<>(inlineTsFmtSettings); + this.buildDir = requireNonNull(buildDir); + this.baseDir = requireNonNull(baseDir); + this.configFile = configFile; + this.inlineTsFmtSettings = inlineTsFmtSettings == null ? new TreeMap<>() : new TreeMap<>(inlineTsFmtSettings); } @Override @@ -146,25 +140,17 @@ private V8FunctionWrapper createFormatResultCallback(NodeJSWrapper nodeJSWrapper } private Map unifyOptions() { - Map unified = new HashMap<>(this.tsFmtCliOptions); - + Map unified = new HashMap<>(); if (!this.inlineTsFmtSettings.isEmpty()) { - removeAllConfigFileSettings(unified); File targetFile = new File(this.buildDir, "inline-tsfmt.json"); SimpleJsonWriter.of(this.inlineTsFmtSettings).toJsonFile(targetFile); unified.put("tsfmt", true); unified.put("tsfmtFile", targetFile.getAbsolutePath()); + } else if (this.configFile != null) { + unified.put(this.configFile.configFileEnabledOptionName(), Boolean.TRUE); + unified.put(this.configFile.configFileOptionName(), this.configFile.absolutePath()); } return unified; } - - private void removeAllConfigFileSettings(Map settings) { - Arrays.asList("tsconfig", "tslint", "editorconfig", "vscode", "tsfmt").forEach( - format -> { - settings.remove(format); - settings.remove(format + "File"); - }); - } - } } diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TypedTsFmtConfigFile.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TypedTsFmtConfigFile.java new file mode 100644 index 0000000000..003dee524f --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TypedTsFmtConfigFile.java @@ -0,0 +1,76 @@ +/* + * 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.extra.npm; + +import static java.util.Objects.requireNonNull; + +import java.io.File; +import java.io.IOException; +import java.io.Serializable; +import java.util.Locale; + +import com.diffplug.common.base.Errors; +import com.diffplug.spotless.FileSignature; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + +public class TypedTsFmtConfigFile implements Serializable { + + private static final long serialVersionUID = -4442310349275775501L; + + private final TsConfigFileType configFileType; + + private final File configFile; + + @SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED") + @SuppressWarnings("unused") + private final FileSignature configFileSignature; + + public TypedTsFmtConfigFile(TsConfigFileType configFileType, File configFile) { + this.configFileType = requireNonNull(configFileType); + this.configFile = requireNonNull(configFile); + try { + this.configFileSignature = FileSignature.signAsList(configFile); + } catch (IOException e) { + throw Errors.asRuntime(e); + } + } + + TsConfigFileType configFileType() { + return configFileType; + } + + File configFile() { + return configFile; + } + + String configFileEnabledOptionName() { + return this.configFileType.name().toLowerCase(Locale.ENGLISH); + } + + String configFileOptionName() { + return this.configFileEnabledOptionName() + "File"; + } + + String absolutePath() { + return this.configFile.getAbsolutePath(); + } + + static TypedTsFmtConfigFile named(String name, File file) { + return new TypedTsFmtConfigFile(TsConfigFileType.forNameIgnoreCase(name), file); + } + +} diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java index 5949e76292..cbee2df1a4 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java @@ -15,8 +15,6 @@ */ package com.diffplug.spotless.extra.npm; -import static org.assertj.core.api.Assertions.fail; - import java.io.File; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -65,11 +63,8 @@ public void formattingUsingConfigFile() throws Exception { TestProvisioner.mavenCentral(), buildDir(), npmExecutable(), - ImmutableMap. builder() - .put("basedir", configFile.getParent()) - .put(configFileNameWithoutExtension, Boolean.TRUE) - .put(configFileNameWithoutExtension + "File", configFile.getPath()) - .build(), + configFile.getParentFile(), + TypedTsFmtConfigFile.named(configFileNameWithoutExtension, configFile), Collections.emptyMap()); try (StepHarness stepHarness = StepHarness.forStep(formatterStep)) { @@ -89,9 +84,8 @@ public void formattingUsingInlineConfigWorks() throws Exception { TestProvisioner.mavenCentral(), buildDir(), npmExecutable(), - ImmutableMap. builder() - .put("basedir", buildDir().getAbsolutePath()) - .build(), + buildDir().getAbsoluteFile(), + null, inlineConfig); try (StepHarness stepHarness = StepHarness.forStep(formatterStep)) { @@ -99,33 +93,4 @@ ImmutableMap. builder() } } } - - @Category(NpmTest.class) - @RunWith(Parameterized.class) - public static class TsFmtBlacklistedOptionsTest extends NpmFormatterStepCommonTests { - @Parameterized.Parameter - public String blackListedOption; - - @Parameterized.Parameters(name = "{index}: config option '{0}' is blacklisted") - public static Iterable blacklistedOption() { - return Arrays.asList("dryRun", "replace", "verify"); - } - - @Test(expected = BlacklistedOptionException.class) - public void blacklistedOptionIsThrown() throws Exception { - TsFmtFormatterStep.create( - TestProvisioner.mavenCentral(), - buildDir(), - npmExecutable(), - ImmutableMap. builder() - .put(blackListedOption, Boolean.TRUE) - .build(), - Collections.emptyMap()); - - fail("should never be reached!"); - - } - - } - } diff --git a/plugin-gradle/README.md b/plugin-gradle/README.md index 6dc3969250..e24cc4c9a0 100644 --- a/plugin-gradle/README.md +++ b/plugin-gradle/README.md @@ -307,18 +307,16 @@ set the `target` parameter as described in the [Custom rules](#custom) section. spotless { typescript { // using existing config files - tsfmt().configFile('tslint', '/path/to/repo/tslint.json') + tsfmt().tslintFile('/path/to/repo/tslint.json') } } ``` -Supported config file types are the ones supported by [tsfmt config options](https://github.com/vvakame/typescript-formatter/blob/7764258ad42ac65071399840d1b8701868510ca7/lib/index.ts#L26). -Use the option names of type boolean in the tsfmt config object: `tsconfig`, `tslint`, `editorconfig`, `vscode` or `tsfmt`. For the option `editorconfig`, no path is supported. +Supported config file types are `tsconfigFile`, `tslintFile`, `vscodeFile` and `tsfmtFile`. They are corresponding to the respective +[tsfmt-parameters](https://github.com/vvakame/typescript-formatter/blob/7764258ad42ac65071399840d1b8701868510ca7/lib/index.ts#L27L34). *Please note:* -- The auto-discovery of config files (up the file tree) will not work when using prettier within spotless, - hence you are required to provide absolute file paths for config files. -- The config file type `editorconfig` is only read from its default location (the user'home). - Any value you pass for the path will be ignored. +The auto-discovery of config files (up the file tree) will not work when using tsfmt within spotless, + hence you are required to provide resolvable file paths for config files. ... or alternatively provide the configuration inline ... @@ -333,11 +331,9 @@ spotless { } ``` -See [tsfmt's default config settings](https://github.com/vvakame/typescript-formatter/blob/7764258ad42ac65071399840d1b8701868510ca7/lib/utils.ts#L8) for what is available. - -*Please note:* If both `configFile` and `config` is provided, only `config` is used. - +See [tsfmt's default config settings](https://github.com/vvakame/typescript-formatter/blob/7764258ad42ac65071399840d1b8701868510ca7/lib/utils.ts#L11L32) for what is available. +... and it is also possible to apply `prettier()` instead of `tsfmt()` as formatter. For details see the section about [prettier](#typescript-prettier). ### Prerequisite: tsfmt requires a working NodeJS version @@ -408,6 +404,7 @@ spotless { } ``` + Prettier can also be applied from within the [typescript config block](#typescript-formatter): ```gradle diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java index b3f63b46d2..96cb7e788c 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java @@ -20,13 +20,15 @@ import java.util.Collections; import java.util.Map; import java.util.TreeMap; -import java.util.stream.Collectors; + +import javax.annotation.Nullable; import org.gradle.api.Project; -import com.diffplug.common.base.Strings; import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.extra.npm.TsConfigFileType; import com.diffplug.spotless.extra.npm.TsFmtFormatterStep; +import com.diffplug.spotless.extra.npm.TypedTsFmtConfigFile; public class TypescriptExtension extends FormatExtension { @@ -44,66 +46,59 @@ public TypescriptFormatExtension tsfmt() { public class TypescriptFormatExtension extends NpmStepConfig { - protected Map config = Collections.emptyMap(); + private Map config = Collections.emptyMap(); - protected String configFileType = null; + @Nullable + TsConfigFileType configFileType = null; - protected String configFilePath = null; + @Nullable + Object configFilePath = null; - public TypescriptFormatExtension config(Map config) { + public void config(final Map config) { this.config = new TreeMap<>(requireNonNull(config)); replaceStep(createStep()); - return this; } - public TypescriptFormatExtension configFile(String filetype, String path) { + public void tsconfigFile(final Object path) { + configFile(TsConfigFileType.TSCONFIG, path); + } + + public void tslintFile(final Object path) { + configFile(TsConfigFileType.TSLINT, path); + } + + public void vscodeFile(final Object path) { + configFile(TsConfigFileType.VSCODE, path); + } + + public void tsfmtFile(final Object path) { + configFile(TsConfigFileType.TSFMT, path); + } + + private void configFile(TsConfigFileType filetype, Object path) { this.configFileType = requireNonNull(filetype); - this.configFilePath = path; // might be null for 'editorconfig' + this.configFilePath = requireNonNull(path); replaceStep(createStep()); - return this; } public FormatterStep createStep() { final Project project = getProject(); - Map tsFmtCliOptions = createTsFmtCliOptions(); - return TsFmtFormatterStep.create( GradleProvisioner.fromProject(project), project.getBuildDir(), npmFileOrNull(), - tsFmtCliOptions, + project.getProjectDir(), + typedConfigFile(), config); } - private Map createTsFmtCliOptions() { - Map tsFmtConfig = new TreeMap<>(); - if (!Strings.isNullOrEmpty(this.configFileType)) { - tsFmtConfig.put(this.configFileType, Boolean.TRUE); - if (!Strings.isNullOrEmpty(this.configFilePath) && !this.configFileType.equals("editorconfig")) { - tsFmtConfig.put(this.configFileType + "File", this.configFilePath); - } + private TypedTsFmtConfigFile typedConfigFile() { + if (this.configFileType != null && this.configFilePath != null) { + return new TypedTsFmtConfigFile(this.configFileType, getProject().file(this.configFilePath)); } - tsFmtConfig.put("basedir", getProject().getRootDir().getAbsolutePath()); //by default we use our project dir - return tsFmtConfig; - } - } - - private String toJsonString(Map map) { - final String valueString = map.entrySet() - .stream() - .map(entry -> " " + jsonEscape(entry.getKey()) + ": " + jsonEscape(entry.getValue())) - .collect(Collectors.joining(",\n")); - - return "{\n" + valueString + "\n}"; - } - - private String jsonEscape(Object val) { - requireNonNull(val); - if (val instanceof String) { - return "\"" + val + "\""; + return null; } - return val.toString(); // numbers, booleans - currently nothing else } @Override diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java index de884dede1..1aa184fa36 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java @@ -50,8 +50,8 @@ public void useTsfmtInlineConfig() throws IOException { public void useTsfmtFileConfig() throws IOException { File formattingFile = setFile("tsfmt.json").toLines( "{", - " \"indentSize\": 1,", - " \"convertTabsToSpaces\": true", + " \"indentSize\": 1,", + " \"convertTabsToSpaces\": true", "}"); setFile("build.gradle").toLines( "buildscript { repositories { mavenCentral() } }", @@ -61,7 +61,7 @@ public void useTsfmtFileConfig() throws IOException { "spotless {", " typescript {", " target 'test.ts'", - " tsfmt().configFile('tsfmt', '" + formattingFile.getAbsolutePath() + "')", + " tsfmt().tsfmtFile('" + formattingFile.getAbsolutePath() + "')", " }", "}"); setFile("test.ts").toResource("npm/tsfmt/tsfmt/tsfmt.dirty"); From 6e07578d69067cc8328c2428cce2068ad87621e6 Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Wed, 12 Sep 2018 06:51:04 +0200 Subject: [PATCH 43/45] moving npm based formatters from lib-extra to lib and adapt dependencies where needed. --- README.md | 8 ++++---- lib-extra/build.gradle | 4 ---- .../spotless}/npm/BlacklistedOptionException.java | 2 +- .../com/diffplug/spotless}/npm/NodeJSWrapper.java | 2 +- .../java/com/diffplug/spotless}/npm/NpmConfig.java | 2 +- .../spotless}/npm/NpmExecutableResolver.java | 11 ++++------- .../spotless}/npm/NpmFormatterStepStateBase.java | 13 ++++--------- .../com/diffplug/spotless}/npm/PlatformInfo.java | 8 +++----- .../com/diffplug/spotless}/npm/PrettierConfig.java | 2 +- .../spotless}/npm/PrettierFormatterStep.java | 4 ++-- .../java/com/diffplug/spotless}/npm/Reflective.java | 2 +- .../spotless}/npm/ReflectiveObjectWrapper.java | 2 +- .../diffplug/spotless}/npm/SimpleJsonWriter.java | 6 +++--- .../diffplug/spotless}/npm/TsConfigFileType.java | 2 +- .../diffplug/spotless}/npm/TsFmtFormatterStep.java | 4 ++-- .../com/diffplug/spotless}/npm/TsFmtResult.java | 2 +- .../spotless}/npm/TypedTsFmtConfigFile.java | 6 +++--- .../com/diffplug/spotless}/npm/V8ArrayWrapper.java | 8 +++----- .../diffplug/spotless}/npm/V8FunctionWrapper.java | 2 +- .../spotless}/npm/V8ObjectUtilsWrapper.java | 2 +- .../com/diffplug/spotless}/npm/V8ObjectWrapper.java | 2 +- .../diffplug/spotless}/npm/prettier-package.json | 0 .../com/diffplug/spotless}/npm/tsfmt-package.json | 0 .../diffplug/gradle/spotless/FormatExtension.java | 4 ++-- .../gradle/spotless/TypescriptExtension.java | 6 +++--- testlib/build.gradle | 3 +++ .../spotless}/npm/NpmFormatterStepCommonTests.java | 2 +- .../spotless}/npm/PrettierFormatterStepTest.java | 2 +- .../spotless}/npm/SimpleJsonWriterTest.java | 2 +- .../spotless}/npm/TsFmtFormatterStepTest.java | 2 +- 30 files changed, 51 insertions(+), 64 deletions(-) rename {lib-extra/src/main/java/com/diffplug/spotless/extra => lib/src/main/java/com/diffplug/spotless}/npm/BlacklistedOptionException.java (95%) rename {lib-extra/src/main/java/com/diffplug/spotless/extra => lib/src/main/java/com/diffplug/spotless}/npm/NodeJSWrapper.java (98%) rename {lib-extra/src/main/java/com/diffplug/spotless/extra => lib/src/main/java/com/diffplug/spotless}/npm/NpmConfig.java (96%) rename {lib-extra/src/main/java/com/diffplug/spotless/extra => lib/src/main/java/com/diffplug/spotless}/npm/NpmExecutableResolver.java (91%) rename {lib-extra/src/main/java/com/diffplug/spotless/extra => lib/src/main/java/com/diffplug/spotless}/npm/NpmFormatterStepStateBase.java (91%) rename {lib-extra/src/main/java/com/diffplug/spotless/extra => lib/src/main/java/com/diffplug/spotless}/npm/PlatformInfo.java (90%) rename {lib-extra/src/main/java/com/diffplug/spotless/extra => lib/src/main/java/com/diffplug/spotless}/npm/PrettierConfig.java (97%) rename {lib-extra/src/main/java/com/diffplug/spotless/extra => lib/src/main/java/com/diffplug/spotless}/npm/PrettierFormatterStep.java (98%) rename {lib-extra/src/main/java/com/diffplug/spotless/extra => lib/src/main/java/com/diffplug/spotless}/npm/Reflective.java (99%) rename {lib-extra/src/main/java/com/diffplug/spotless/extra => lib/src/main/java/com/diffplug/spotless}/npm/ReflectiveObjectWrapper.java (98%) rename {lib-extra/src/main/java/com/diffplug/spotless/extra => lib/src/main/java/com/diffplug/spotless}/npm/SimpleJsonWriter.java (95%) rename {lib-extra/src/main/java/com/diffplug/spotless/extra => lib/src/main/java/com/diffplug/spotless}/npm/TsConfigFileType.java (96%) rename {lib-extra/src/main/java/com/diffplug/spotless/extra => lib/src/main/java/com/diffplug/spotless}/npm/TsFmtFormatterStep.java (98%) rename {lib-extra/src/main/java/com/diffplug/spotless/extra => lib/src/main/java/com/diffplug/spotless}/npm/TsFmtResult.java (96%) rename {lib-extra/src/main/java/com/diffplug/spotless/extra => lib/src/main/java/com/diffplug/spotless}/npm/TypedTsFmtConfigFile.java (94%) rename {lib-extra/src/main/java/com/diffplug/spotless/extra => lib/src/main/java/com/diffplug/spotless}/npm/V8ArrayWrapper.java (84%) rename {lib-extra/src/main/java/com/diffplug/spotless/extra => lib/src/main/java/com/diffplug/spotless}/npm/V8FunctionWrapper.java (98%) rename {lib-extra/src/main/java/com/diffplug/spotless/extra => lib/src/main/java/com/diffplug/spotless}/npm/V8ObjectUtilsWrapper.java (96%) rename {lib-extra/src/main/java/com/diffplug/spotless/extra => lib/src/main/java/com/diffplug/spotless}/npm/V8ObjectWrapper.java (98%) rename {lib-extra/src/main/resources/com/diffplug/spotless/extra => lib/src/main/resources/com/diffplug/spotless}/npm/prettier-package.json (100%) rename {lib-extra/src/main/resources/com/diffplug/spotless/extra => lib/src/main/resources/com/diffplug/spotless}/npm/tsfmt-package.json (100%) rename {lib-extra/src/test/java/com/diffplug/spotless/extra => testlib/src/test/java/com/diffplug/spotless}/npm/NpmFormatterStepCommonTests.java (96%) rename {lib-extra/src/test/java/com/diffplug/spotless/extra => testlib/src/test/java/com/diffplug/spotless}/npm/PrettierFormatterStepTest.java (99%) rename {lib-extra/src/test/java/com/diffplug/spotless/extra => testlib/src/test/java/com/diffplug/spotless}/npm/SimpleJsonWriterTest.java (98%) rename {lib-extra/src/test/java/com/diffplug/spotless/extra => testlib/src/test/java/com/diffplug/spotless}/npm/TsFmtFormatterStepTest.java (98%) diff --git a/README.md b/README.md index 6773e86be7..5fba202055 100644 --- a/README.md +++ b/README.md @@ -45,8 +45,8 @@ lib('java.RemoveUnusedImportsStep') +'{{yes}} | {{yes}} extra('java.EclipseFormatterStep') +'{{yes}} | {{yes}} | {{no}} |', lib('kotlin.KtLintStep') +'{{yes}} | {{yes}} | {{no}} |', lib('markdown.FreshMarkStep') +'{{yes}} | {{no}} | {{no}} |', -extra('npm.PrettierFormatterStep') +'{{yes}} | {{no}} | {{no}} |', -extra('npm.TsFmtFormatterStep') +'{{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}} |', '| [(Your FormatterStep here)](CONTRIBUTING.md#how-to-add-a-new-formatterstep) | {{no}} | {{no}} | {{no}} |', @@ -70,8 +70,8 @@ lib('sql.DBeaverSQLFormatterStep') +'{{yes}} | {{no}} | [`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-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java) | :+1: | :white_large_square: | :white_large_square: | -| [`npm.TsFmtFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.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: | | [(Your FormatterStep here)](CONTRIBUTING.md#how-to-add-a-new-formatterstep) | :white_large_square: | :white_large_square: | :white_large_square: | diff --git a/lib-extra/build.gradle b/lib-extra/build.gradle index 95eef4046c..45a754cded 100644 --- a/lib-extra/build.gradle +++ b/lib-extra/build.gradle @@ -23,7 +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) - -test { useJUnit { excludeCategories 'com.diffplug.spotless.category.NpmTest' } } - -task npmTest(type: Test) { useJUnit { includeCategories 'com.diffplug.spotless.category.NpmTest' } } diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/BlacklistedOptionException.java b/lib/src/main/java/com/diffplug/spotless/npm/BlacklistedOptionException.java similarity index 95% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/BlacklistedOptionException.java rename to lib/src/main/java/com/diffplug/spotless/npm/BlacklistedOptionException.java index f82751274d..3704f487dc 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/BlacklistedOptionException.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/BlacklistedOptionException.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; class BlacklistedOptionException extends RuntimeException { private static final long serialVersionUID = -5876348893394153811L; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NodeJSWrapper.java b/lib/src/main/java/com/diffplug/spotless/npm/NodeJSWrapper.java similarity index 98% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NodeJSWrapper.java rename to lib/src/main/java/com/diffplug/spotless/npm/NodeJSWrapper.java index 407865680f..1ae4efd199 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NodeJSWrapper.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/NodeJSWrapper.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; import java.io.File; import java.util.Map; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmConfig.java b/lib/src/main/java/com/diffplug/spotless/npm/NpmConfig.java similarity index 96% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmConfig.java rename to lib/src/main/java/com/diffplug/spotless/npm/NpmConfig.java index 768f995af5..55d3683606 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmConfig.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/NpmConfig.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; import java.io.Serializable; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmExecutableResolver.java b/lib/src/main/java/com/diffplug/spotless/npm/NpmExecutableResolver.java similarity index 91% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmExecutableResolver.java rename to lib/src/main/java/com/diffplug/spotless/npm/NpmExecutableResolver.java index 760f704727..cbbf6bc6bd 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmExecutableResolver.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/NpmExecutableResolver.java @@ -13,17 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; -import static com.diffplug.spotless.extra.npm.PlatformInfo.OS.WINDOWS; +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; -import com.diffplug.common.base.Splitter; - /** * Utility class to resolve an npm binary to be used by npm-based steps. * Tries to find an npm executable in the following order: @@ -84,9 +83,7 @@ private static Supplier> pathListFromEnvironment(String environme return () -> { String pathList = System.getenv(environmentPathListName); if (pathList != null) { - return Splitter.on(System.getProperty("path.separator", ":")) - .splitToList(pathList) - .stream() + 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())) diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java b/lib/src/main/java/com/diffplug/spotless/npm/NpmFormatterStepStateBase.java similarity index 91% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java rename to lib/src/main/java/com/diffplug/spotless/npm/NpmFormatterStepStateBase.java index 94f7e68222..1fc056fa0d 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/NpmFormatterStepStateBase.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/NpmFormatterStepStateBase.java @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; -import static com.diffplug.spotless.extra.npm.NpmExecutableResolver.tryFind; import static java.util.Objects.requireNonNull; import java.io.ByteArrayOutputStream; @@ -29,11 +28,7 @@ import javax.annotation.Nullable; -import com.diffplug.common.base.Errors; -import com.diffplug.spotless.FileSignature; -import com.diffplug.spotless.FormatterFunc; -import com.diffplug.spotless.JarState; -import com.diffplug.spotless.Provisioner; +import com.diffplug.spotless.*; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -92,7 +87,7 @@ private void runNpmInstall(@Nullable File npm, File npmProjectDir) throws IOExce private File resolveNpm(@Nullable File npm) { return Optional.ofNullable(npm) - .orElseGet(() -> tryFind() + .orElseGet(() -> NpmExecutableResolver.tryFind() .orElseThrow(() -> new IllegalStateException("cannot automatically determine npm executable and none was specifically supplied!"))); } @@ -118,7 +113,7 @@ protected static String readFileFromClasspath(Class clazz, String name) { } return output.toString(StandardCharsets.UTF_8.name()); } catch (IOException e) { - throw Errors.asRuntime(e); + throw ThrowingEx.asRuntime(e); } } diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PlatformInfo.java b/lib/src/main/java/com/diffplug/spotless/npm/PlatformInfo.java similarity index 90% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PlatformInfo.java rename to lib/src/main/java/com/diffplug/spotless/npm/PlatformInfo.java index de49ca5f31..2065b0ca54 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PlatformInfo.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/PlatformInfo.java @@ -13,21 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; import static java.util.Objects.requireNonNull; import java.util.Locale; -import com.diffplug.common.base.StandardSystemProperty; - class PlatformInfo { private PlatformInfo() { // no instance } static OS normalizedOS() { - final String osNameProperty = StandardSystemProperty.OS_NAME.value(); + final String osNameProperty = System.getProperty("os.name"); if (osNameProperty == null) { throw new RuntimeException("No info about OS available, cannot decide which implementation of j2v8 to use"); } @@ -49,7 +47,7 @@ static String normalizedOSName() { } static String normalizedArchName() { - final String osArchProperty = StandardSystemProperty.OS_ARCH.value(); + final String osArchProperty = System.getProperty("os.arch"); if (osArchProperty == null) { throw new RuntimeException("No info about ARCH available, cannot decide which implementation of j2v8 to use"); } diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierConfig.java b/lib/src/main/java/com/diffplug/spotless/npm/PrettierConfig.java similarity index 97% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierConfig.java rename to lib/src/main/java/com/diffplug/spotless/npm/PrettierConfig.java index 214eec5d67..328cb25a4e 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierConfig.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/PrettierConfig.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; import java.io.File; import java.io.IOException; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java b/lib/src/main/java/com/diffplug/spotless/npm/PrettierFormatterStep.java similarity index 98% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java rename to lib/src/main/java/com/diffplug/spotless/npm/PrettierFormatterStep.java index 4aaa23cd08..56842ef413 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/PrettierFormatterStep.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/PrettierFormatterStep.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; import static java.util.Arrays.asList; import static java.util.Objects.requireNonNull; @@ -53,7 +53,7 @@ public static class State extends NpmFormatterStepStateBase implements Serializa super(stepName, provisioner, new NpmConfig( - readFileFromClasspath(PrettierFormatterStep.class, "/com/diffplug/spotless/extra/npm/prettier-package.json"), + readFileFromClasspath(PrettierFormatterStep.class, "/com/diffplug/spotless/npm/prettier-package.json"), "prettier"), buildDir, npm); diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java b/lib/src/main/java/com/diffplug/spotless/npm/Reflective.java similarity index 99% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java rename to lib/src/main/java/com/diffplug/spotless/npm/Reflective.java index c68fe43fb0..5f68606fa7 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/Reflective.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/Reflective.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; import static java.util.Objects.requireNonNull; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/ReflectiveObjectWrapper.java b/lib/src/main/java/com/diffplug/spotless/npm/ReflectiveObjectWrapper.java similarity index 98% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/ReflectiveObjectWrapper.java rename to lib/src/main/java/com/diffplug/spotless/npm/ReflectiveObjectWrapper.java index e10b23a366..3dfffc8c94 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/ReflectiveObjectWrapper.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/ReflectiveObjectWrapper.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; import static java.util.Objects.requireNonNull; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/SimpleJsonWriter.java b/lib/src/main/java/com/diffplug/spotless/npm/SimpleJsonWriter.java similarity index 95% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/SimpleJsonWriter.java rename to lib/src/main/java/com/diffplug/spotless/npm/SimpleJsonWriter.java index 9f786cf484..8650f086c4 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/SimpleJsonWriter.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/SimpleJsonWriter.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; import static java.util.Objects.requireNonNull; @@ -26,7 +26,7 @@ import java.util.Map; import java.util.stream.Collectors; -import com.diffplug.common.base.Errors; +import com.diffplug.spotless.ThrowingEx; public class SimpleJsonWriter { @@ -83,7 +83,7 @@ void toJsonFile(File file) { try { Files.write(file.toPath(), toJsonString().getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { - throw Errors.asRuntime(e); + throw ThrowingEx.asRuntime(e); } } diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsConfigFileType.java b/lib/src/main/java/com/diffplug/spotless/npm/TsConfigFileType.java similarity index 96% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsConfigFileType.java rename to lib/src/main/java/com/diffplug/spotless/npm/TsConfigFileType.java index 5e118ad81e..19251f7a76 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsConfigFileType.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/TsConfigFileType.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; import java.util.Arrays; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java b/lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java similarity index 98% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java rename to lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java index 320c638b08..52d7a31d2b 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStep.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; import static java.util.Arrays.asList; import static java.util.Objects.requireNonNull; @@ -61,7 +61,7 @@ public State(String stepName, Provisioner provisioner, File buildDir, @Nullable super(stepName, provisioner, new NpmConfig( - readFileFromClasspath(TsFmtFormatterStep.class, "/com/diffplug/spotless/extra/npm/tsfmt-package.json"), + readFileFromClasspath(TsFmtFormatterStep.class, "/com/diffplug/spotless/npm/tsfmt-package.json"), "typescript-formatter"), buildDir, npm); diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtResult.java b/lib/src/main/java/com/diffplug/spotless/npm/TsFmtResult.java similarity index 96% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtResult.java rename to lib/src/main/java/com/diffplug/spotless/npm/TsFmtResult.java index 7ca8418a17..c43f4963f3 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TsFmtResult.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/TsFmtResult.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; class TsFmtResult { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TypedTsFmtConfigFile.java b/lib/src/main/java/com/diffplug/spotless/npm/TypedTsFmtConfigFile.java similarity index 94% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TypedTsFmtConfigFile.java rename to lib/src/main/java/com/diffplug/spotless/npm/TypedTsFmtConfigFile.java index 003dee524f..9968c5c068 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/TypedTsFmtConfigFile.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/TypedTsFmtConfigFile.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; import static java.util.Objects.requireNonNull; @@ -22,8 +22,8 @@ import java.io.Serializable; import java.util.Locale; -import com.diffplug.common.base.Errors; import com.diffplug.spotless.FileSignature; +import com.diffplug.spotless.ThrowingEx; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -45,7 +45,7 @@ public TypedTsFmtConfigFile(TsConfigFileType configFileType, File configFile) { try { this.configFileSignature = FileSignature.signAsList(configFile); } catch (IOException e) { - throw Errors.asRuntime(e); + throw ThrowingEx.asRuntime(e); } } diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ArrayWrapper.java b/lib/src/main/java/com/diffplug/spotless/npm/V8ArrayWrapper.java similarity index 84% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ArrayWrapper.java rename to lib/src/main/java/com/diffplug/spotless/npm/V8ArrayWrapper.java index 7dba2f354b..0d26df0b64 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ArrayWrapper.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/V8ArrayWrapper.java @@ -13,9 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; - -import static com.diffplug.spotless.extra.npm.NodeJSWrapper.V8_VALUE_CLASS; +package com.diffplug.spotless.npm; public class V8ArrayWrapper extends ReflectiveObjectWrapper { @@ -30,8 +28,8 @@ public V8ArrayWrapper push(Object object) { ReflectiveObjectWrapper objectWrapper = (ReflectiveObjectWrapper) object; object = objectWrapper.wrappedObj(); } - if (reflective().clazz(V8_VALUE_CLASS).isAssignableFrom(object.getClass())) { - invoke("push", reflective().typed(V8_VALUE_CLASS, object)); + if (reflective().clazz(NodeJSWrapper.V8_VALUE_CLASS).isAssignableFrom(object.getClass())) { + invoke("push", reflective().typed(NodeJSWrapper.V8_VALUE_CLASS, object)); } else { invoke("push", object); } diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8FunctionWrapper.java b/lib/src/main/java/com/diffplug/spotless/npm/V8FunctionWrapper.java similarity index 98% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8FunctionWrapper.java rename to lib/src/main/java/com/diffplug/spotless/npm/V8FunctionWrapper.java index 9eefa13a61..36a9804854 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8FunctionWrapper.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/V8FunctionWrapper.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; import java.lang.reflect.Method; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectUtilsWrapper.java b/lib/src/main/java/com/diffplug/spotless/npm/V8ObjectUtilsWrapper.java similarity index 96% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectUtilsWrapper.java rename to lib/src/main/java/com/diffplug/spotless/npm/V8ObjectUtilsWrapper.java index 0bd785795f..af7448c748 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectUtilsWrapper.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/V8ObjectUtilsWrapper.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; import static java.util.Objects.requireNonNull; diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectWrapper.java b/lib/src/main/java/com/diffplug/spotless/npm/V8ObjectWrapper.java similarity index 98% rename from lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectWrapper.java rename to lib/src/main/java/com/diffplug/spotless/npm/V8ObjectWrapper.java index ca5d69eaa1..917e25c222 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/npm/V8ObjectWrapper.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/V8ObjectWrapper.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; import java.util.Optional; diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/prettier-package.json b/lib/src/main/resources/com/diffplug/spotless/npm/prettier-package.json similarity index 100% rename from lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/prettier-package.json rename to lib/src/main/resources/com/diffplug/spotless/npm/prettier-package.json diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/tsfmt-package.json b/lib/src/main/resources/com/diffplug/spotless/npm/tsfmt-package.json similarity index 100% rename from lib-extra/src/main/resources/com/diffplug/spotless/extra/npm/tsfmt-package.json rename to lib/src/main/resources/com/diffplug/spotless/npm/tsfmt-package.json diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java index 1ab9bad52f..e19e88e356 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java @@ -35,13 +35,13 @@ import com.diffplug.spotless.LazyForwardingEquality; import com.diffplug.spotless.LineEnding; import com.diffplug.spotless.ThrowingEx; -import com.diffplug.spotless.extra.npm.PrettierFormatterStep; import com.diffplug.spotless.generic.EndWithNewlineStep; import com.diffplug.spotless.generic.IndentStep; import com.diffplug.spotless.generic.LicenseHeaderStep; import com.diffplug.spotless.generic.ReplaceRegexStep; import com.diffplug.spotless.generic.ReplaceStep; import com.diffplug.spotless.generic.TrimTrailingWhitespaceStep; +import com.diffplug.spotless.npm.PrettierFormatterStep; import groovy.lang.Closure; @@ -471,7 +471,7 @@ FormatterStep createStep() { GradleProvisioner.fromProject(project), project.getBuildDir(), npmFileOrNull(), - new com.diffplug.spotless.extra.npm.PrettierConfig( + new com.diffplug.spotless.npm.PrettierConfig( this.prettierConfigFile != null ? project.file(this.prettierConfigFile) : null, this.prettierConfig)); } diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java index 96cb7e788c..b20a4e34c1 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java @@ -26,9 +26,9 @@ import org.gradle.api.Project; import com.diffplug.spotless.FormatterStep; -import com.diffplug.spotless.extra.npm.TsConfigFileType; -import com.diffplug.spotless.extra.npm.TsFmtFormatterStep; -import com.diffplug.spotless.extra.npm.TypedTsFmtConfigFile; +import com.diffplug.spotless.npm.TsConfigFileType; +import com.diffplug.spotless.npm.TsFmtFormatterStep; +import com.diffplug.spotless.npm.TypedTsFmtConfigFile; public class TypescriptExtension extends FormatExtension { diff --git a/testlib/build.gradle b/testlib/build.gradle index 8aa81bd9a9..752d26f0eb 100644 --- a/testlib/build.gradle +++ b/testlib/build.gradle @@ -15,3 +15,6 @@ dependencies { // we'll hold the testlib to a low standard (prize brevity) spotbugs { reportLevel = 'high' } // low|medium|high (low = sensitive to even minor mistakes) +test { useJUnit { excludeCategories 'com.diffplug.spotless.category.NpmTest' } } + +task npmTest(type: Test) { useJUnit { includeCategories 'com.diffplug.spotless.category.NpmTest' } } diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmFormatterStepCommonTests.java b/testlib/src/test/java/com/diffplug/spotless/npm/NpmFormatterStepCommonTests.java similarity index 96% rename from lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmFormatterStepCommonTests.java rename to testlib/src/test/java/com/diffplug/spotless/npm/NpmFormatterStepCommonTests.java index e519892c2a..79b58ab5a9 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/NpmFormatterStepCommonTests.java +++ b/testlib/src/test/java/com/diffplug/spotless/npm/NpmFormatterStepCommonTests.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; import java.io.File; import java.io.IOException; diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java b/testlib/src/test/java/com/diffplug/spotless/npm/PrettierFormatterStepTest.java similarity index 99% rename from lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java rename to testlib/src/test/java/com/diffplug/spotless/npm/PrettierFormatterStepTest.java index 0f9440ac3b..508a49a28a 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/PrettierFormatterStepTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/npm/PrettierFormatterStepTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; import java.io.File; import java.util.Arrays; diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/SimpleJsonWriterTest.java b/testlib/src/test/java/com/diffplug/spotless/npm/SimpleJsonWriterTest.java similarity index 98% rename from lib-extra/src/test/java/com/diffplug/spotless/extra/npm/SimpleJsonWriterTest.java rename to testlib/src/test/java/com/diffplug/spotless/npm/SimpleJsonWriterTest.java index 69e13e2531..787bba49ff 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/SimpleJsonWriterTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/npm/SimpleJsonWriterTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.*; diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java b/testlib/src/test/java/com/diffplug/spotless/npm/TsFmtFormatterStepTest.java similarity index 98% rename from lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java rename to testlib/src/test/java/com/diffplug/spotless/npm/TsFmtFormatterStepTest.java index cbee2df1a4..773f355ecf 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/npm/TsFmtFormatterStepTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/npm/TsFmtFormatterStepTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.spotless.extra.npm; +package com.diffplug.spotless.npm; import java.io.File; import java.nio.charset.StandardCharsets; From ade884af97528b8cc284cae3ef249c02db083d12 Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Wed, 12 Sep 2018 11:04:34 +0200 Subject: [PATCH 44/45] fixes for running on windows --- .../com/diffplug/spotless/npm/NodeJSWrapper.java | 11 ++++++++++- .../spotless/npm/NpmExecutableResolver.java | 15 ++++++++++++--- .../gradle/spotless/PrettierIntegrationTest.java | 5 ++--- .../gradle/spotless/TypescriptExtensionTest.java | 5 ++--- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/lib/src/main/java/com/diffplug/spotless/npm/NodeJSWrapper.java b/lib/src/main/java/com/diffplug/spotless/npm/NodeJSWrapper.java index 1ae4efd199..bdb535591a 100644 --- a/lib/src/main/java/com/diffplug/spotless/npm/NodeJSWrapper.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/NodeJSWrapper.java @@ -18,6 +18,7 @@ import java.io.File; import java.util.Map; import java.util.Objects; +import java.util.concurrent.atomic.AtomicBoolean; class NodeJSWrapper extends ReflectiveObjectWrapper { @@ -26,9 +27,17 @@ class NodeJSWrapper extends ReflectiveObjectWrapper { 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 -> reflective.invokeStaticMethod(WRAPPED_CLASS, "createNodeJS")); + 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) { diff --git a/lib/src/main/java/com/diffplug/spotless/npm/NpmExecutableResolver.java b/lib/src/main/java/com/diffplug/spotless/npm/NpmExecutableResolver.java index cbbf6bc6bd..cea0984a2f 100644 --- a/lib/src/main/java/com/diffplug/spotless/npm/NpmExecutableResolver.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/NpmExecutableResolver.java @@ -31,6 +31,7 @@ *
  • from Environment-Properties in the following order:
  • *
      *
    1. from NVM_BIN environment variable, if available
    2. + *
    3. from NVM_SYMLINK environment variable, if available
    4. *
    5. from NODE_PATH environment variable, if available
    6. *
    7. fallback: PATH environment variable
    8. *
    @@ -45,7 +46,7 @@ private NpmExecutableResolver() { static String npmExecutableName() { String npmName = "npm"; if (PlatformInfo.normalizedOS() == WINDOWS) { - npmName += ".exe"; + npmName += ".cmd"; } return npmName; } @@ -55,7 +56,7 @@ static Supplier> systemProperty() { .map(File::new); } - static Supplier> environmentNvm() { + static Supplier> environmentNvmBin() { return () -> Optional.ofNullable(System.getenv("NVM_BIN")) .map(File::new) .map(binDir -> new File(binDir, npmExecutableName())) @@ -63,6 +64,10 @@ static Supplier> environmentNvm() { .filter(File::canExecute); } + static Supplier> environmentNvmSymlink() { + return pathListFromEnvironment("NVM_SYMLINK"); + } + static Supplier> environmentNodepath() { return pathListFromEnvironment("NODE_PATH"); } @@ -72,7 +77,11 @@ static Supplier> environmentPath() { } static Optional tryFind() { - return Stream.of(systemProperty(), environmentNvm(), environmentNodepath(), environmentPath()) + return Stream.of(systemProperty(), + environmentNvmBin(), + environmentNvmSymlink(), + environmentNodepath(), + environmentPath()) .map(Supplier::get) .filter(Optional::isPresent) .map(Optional::get) diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/PrettierIntegrationTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/PrettierIntegrationTest.java index f850225878..7a0d374e49 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/PrettierIntegrationTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/PrettierIntegrationTest.java @@ -15,7 +15,6 @@ */ package com.diffplug.gradle.spotless; -import java.io.File; import java.io.IOException; import org.junit.Test; @@ -48,7 +47,7 @@ public void useInlineConfig() throws IOException { @Test public void useFileConfig() throws IOException { - File formattingFile = setFile(".prettierrc.yml").toResource("npm/prettier/config/.prettierrc.yml"); + setFile(".prettierrc.yml").toResource("npm/prettier/config/.prettierrc.yml"); setFile("build.gradle").toLines( "buildscript { repositories { mavenCentral() } }", "plugins {", @@ -57,7 +56,7 @@ public void useFileConfig() throws IOException { "spotless {", " format 'mytypescript', {", " target 'test.ts'", - " prettier().configFile('" + formattingFile.getAbsolutePath() + "')", + " prettier().configFile('.prettierrc.yml')", " }", "}"); setFile("test.ts").toResource("npm/prettier/config/typescript.dirty"); diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java index 1aa184fa36..6904b62b9c 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java @@ -15,7 +15,6 @@ */ package com.diffplug.gradle.spotless; -import java.io.File; import java.io.IOException; import org.junit.Test; @@ -48,7 +47,7 @@ public void useTsfmtInlineConfig() throws IOException { @Test public void useTsfmtFileConfig() throws IOException { - File formattingFile = setFile("tsfmt.json").toLines( + setFile("tsfmt.json").toLines( "{", " \"indentSize\": 1,", " \"convertTabsToSpaces\": true", @@ -61,7 +60,7 @@ public void useTsfmtFileConfig() throws IOException { "spotless {", " typescript {", " target 'test.ts'", - " tsfmt().tsfmtFile('" + formattingFile.getAbsolutePath() + "')", + " tsfmt().tsfmtFile('tsfmt.json')", " }", "}"); setFile("test.ts").toResource("npm/tsfmt/tsfmt/tsfmt.dirty"); From 807bf7ba750fa935d1160472e98c2da987c009d3 Mon Sep 17 00:00:00 2001 From: Simon Gamma Date: Thu, 13 Sep 2018 17:07:16 +0200 Subject: [PATCH 45/45] integrating PR feedback --- .../main/java/com/diffplug/spotless/JarState.java | 12 +++++++++--- .../java/com/diffplug/spotless/npm/PlatformInfo.java | 4 ++-- .../java/com/diffplug/spotless/npm/Reflective.java | 4 ---- .../diffplug/spotless/npm/TypedTsFmtConfigFile.java | 2 +- plugin-gradle/README.md | 12 ++++++++---- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/lib/src/main/java/com/diffplug/spotless/JarState.java b/lib/src/main/java/com/diffplug/spotless/JarState.java index 8d3506a2bb..faaaa43ca3 100644 --- a/lib/src/main/java/com/diffplug/spotless/JarState.java +++ b/lib/src/main/java/com/diffplug/spotless/JarState.java @@ -20,7 +20,13 @@ import java.io.Serializable; import java.net.URI; import java.net.URL; -import java.util.*; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.Set; +import java.util.TreeSet; import java.util.stream.Collectors; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -29,7 +35,7 @@ * Grabs a jar and its dependencies from maven, * and makes it easy to access the collection in * a classloader. - *

    + * * Serializes the full state of the jar, so it can * catch changes in a SNAPSHOT version. */ @@ -79,7 +85,7 @@ URL[] jarUrls() { /** * Returns a classloader containing only the jars in this JarState. - *

    + * * The lifetime of the underlying cacheloader is controlled by {@link SpotlessCache}. */ public ClassLoader getClassLoader() { diff --git a/lib/src/main/java/com/diffplug/spotless/npm/PlatformInfo.java b/lib/src/main/java/com/diffplug/spotless/npm/PlatformInfo.java index 2065b0ca54..3ae624d7c0 100644 --- a/lib/src/main/java/com/diffplug/spotless/npm/PlatformInfo.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/PlatformInfo.java @@ -29,7 +29,7 @@ static OS normalizedOS() { if (osNameProperty == null) { throw new RuntimeException("No info about OS available, cannot decide which implementation of j2v8 to use"); } - final String normalizedOsName = osNameProperty.toLowerCase(Locale.ENGLISH); + final String normalizedOsName = osNameProperty.toLowerCase(Locale.ROOT); if (normalizedOsName.contains("win")) { return OS.WINDOWS; } @@ -51,7 +51,7 @@ static String normalizedArchName() { if (osArchProperty == null) { throw new RuntimeException("No info about ARCH available, cannot decide which implementation of j2v8 to use"); } - final String normalizedOsArch = osArchProperty.toLowerCase(Locale.ENGLISH); + final String normalizedOsArch = osArchProperty.toLowerCase(Locale.ROOT); if (normalizedOsArch.contains("64")) { return "x86_64"; diff --git a/lib/src/main/java/com/diffplug/spotless/npm/Reflective.java b/lib/src/main/java/com/diffplug/spotless/npm/Reflective.java index 5f68606fa7..e1076672b9 100644 --- a/lib/src/main/java/com/diffplug/spotless/npm/Reflective.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/Reflective.java @@ -97,8 +97,6 @@ private Method method(Object target, Class clazz, String methodName, Object[] if (clazz.getSuperclass() != null) { return method(target, clazz.getSuperclass(), methodName, parameters); } else { - // try with primitives - throw new ReflectiveException("Could not find method " + methodName + " with parameters " + Arrays.toString(parameters) + " on object " + target, e); } } @@ -112,8 +110,6 @@ private Method method(Object target, Class clazz, String methodName, TypedVal if (clazz.getSuperclass() != null) { return method(target, clazz.getSuperclass(), methodName, parameters); } else { - // try with primitives - throw new ReflectiveException("Could not find method " + methodName + " with parameters " + Arrays.toString(parameters) + " on object " + target, e); } } diff --git a/lib/src/main/java/com/diffplug/spotless/npm/TypedTsFmtConfigFile.java b/lib/src/main/java/com/diffplug/spotless/npm/TypedTsFmtConfigFile.java index 9968c5c068..75257711f6 100644 --- a/lib/src/main/java/com/diffplug/spotless/npm/TypedTsFmtConfigFile.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/TypedTsFmtConfigFile.java @@ -58,7 +58,7 @@ File configFile() { } String configFileEnabledOptionName() { - return this.configFileType.name().toLowerCase(Locale.ENGLISH); + return this.configFileType.name().toLowerCase(Locale.ROOT); } String configFileOptionName() { diff --git a/plugin-gradle/README.md b/plugin-gradle/README.md index e24cc4c9a0..520cdd976f 100644 --- a/plugin-gradle/README.md +++ b/plugin-gradle/README.md @@ -348,6 +348,8 @@ spotless { } ``` +Spotless uses npm to install necessary packages locally. It runs tsfmt using [J2V8](https://github.com/eclipsesource/J2V8) internally after that. + ## Applying [Prettier](https://prettier.io) to javascript | flow | typeScript | css | scss | less | jsx | graphQL | yaml | etc. @@ -379,10 +381,9 @@ spotless { format 'styling', { target '**/*.css', '**/*.scss' - // or provide both (config options will win over configFile options) prettier().configFile('/path-to/.prettierrc.yml') - // or provide both (config options will win over configFile options) + // or provide both (config options take precedence over configFile options) prettier().config(['parser': 'postcss']).configFile('path-to/.prettierrc.yml') } } @@ -411,7 +412,7 @@ Prettier can also be applied from within the [typescript config block](#typescri spotless { typescript { // no parser or filepath needed - // -> will default to 'typesript' parser when used in the typescript block + // -> will default to 'typescript' parser when used in the typescript block prettier() } } @@ -419,7 +420,7 @@ spotless { ### Prerequisite: prettier requires a working NodeJS version -prettier, like tsfmt, is based on NodeJS, so to use it, a working NodeJS installation (especially npm) is required on the host running spotless. +Prettier, like tsfmt, is based on NodeJS, so to use it, a working NodeJS installation (especially npm) is required on the host running spotless. 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. ```gradle @@ -429,6 +430,9 @@ spotless { } } ``` + +Spotless uses npm to install necessary packages locally. It runs prettier using [J2V8](https://github.com/eclipsesource/J2V8) internally after that. + ## License header options