diff --git a/README.md b/README.md index 5c311133da..c5a1de180d 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ extra('java.EclipseFormatterStep') +'{{yes}} | {{yes}} lib('kotlin.KtLintStep') +'{{yes}} | {{yes}} | {{no}} |', lib('markdown.FreshMarkStep') +'{{yes}} | {{no}} | {{no}} |', lib('npm.PrettierFormatterStep') +'{{yes}} | {{no}} | {{no}} |', -lib('npm.TsFmtFormatterStep') +'{{yes}} | {{no}} | {{no}} |', +lib('npm.TsFmtFormatterStep') +'{{yes}} | {{yes}} | {{no}} |', lib('scala.ScalaFmtStep') +'{{yes}} | {{yes}} | {{no}} |', lib('sql.DBeaverSQLFormatterStep') +'{{yes}} | {{no}} | {{no}} |', extra('wtp.EclipseWtpFormatterStep') +'{{yes}} | {{yes}} | {{no}} |', @@ -74,7 +74,7 @@ extra('wtp.EclipseWtpFormatterStep') +'{{yes}} | {{yes}} | [`kotlin.KtLintStep`](lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java) | :+1: | :+1: | :white_large_square: | | [`markdown.FreshMarkStep`](lib/src/main/java/com/diffplug/spotless/markdown/FreshMarkStep.java) | :+1: | :white_large_square: | :white_large_square: | | [`npm.PrettierFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/PrettierFormatterStep.java) | :+1: | :white_large_square: | :white_large_square: | -| [`npm.TsFmtFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java) | :+1: | :white_large_square: | :white_large_square: | +| [`npm.TsFmtFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java) | :+1: | :+1: | :white_large_square: | | [`scala.ScalaFmtStep`](lib/src/main/java/com/diffplug/spotless/scala/ScalaFmtStep.java) | :+1: | :+1: | :white_large_square: | | [`sql.DBeaverSQLFormatterStep`](lib/src/main/java/com/diffplug/spotless/sql/DBeaverSQLFormatterStep.java) | :+1: | :white_large_square: | :white_large_square: | | [`wtp.EclipseWtpFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/wtp/EclipseWtpFormatterStep.java) | :+1: | :+1: | :white_large_square: | 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 bdb535591a..85cb8467f2 100644 --- a/lib/src/main/java/com/diffplug/spotless/npm/NodeJSWrapper.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/NodeJSWrapper.java @@ -20,6 +20,8 @@ import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; +import com.diffplug.spotless.LineEnding; + class NodeJSWrapper extends ReflectiveObjectWrapper { public static final String V8_RUNTIME_CLASS = "com.eclipsesource.v8.V8"; @@ -33,7 +35,7 @@ public NodeJSWrapper(ClassLoader classLoader) { super(Reflective.withClassLoader(classLoader), reflective -> { final boolean firstRun = flagsSet.compareAndSet(false, true); - if (firstRun) { + if (firstRun && LineEnding.PLATFORM_NATIVE.str().equals("\r\n")) { reflective.invokeStaticMethod(V8_RUNTIME_CLASS, "setFlags", "-color=false"); // required to run prettier on windows } return reflective.invokeStaticMethod(WRAPPED_CLASS, "createNodeJS"); 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 51905a0fde..677f135b70 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 @@ -89,11 +89,7 @@ public void useTsfmtInlineConfig() throws IOException { @Test public void useTsfmtFileConfig() throws IOException { - setFile("tsfmt.json").toLines( - "{", - " \"indentSize\": 1,", - " \"convertTabsToSpaces\": true", - "}"); + setFile("tsfmt.json").toResource("npm/tsfmt/tsfmt/tsfmt.json"); setFile("build.gradle").toLines( "buildscript { repositories { mavenCentral() } }", "plugins {", @@ -110,6 +106,24 @@ public void useTsfmtFileConfig() throws IOException { assertFile("test.ts").sameAsResource("npm/tsfmt/tsfmt/tsfmt.clean"); } + @Test + public void useTsConfigFileConfig() throws IOException { + setFile("tsconfig.json").toResource("npm/tsfmt/tsconfig/tsconfig.json"); + setFile("build.gradle").toLines( + "buildscript { repositories { mavenCentral() } }", + "plugins {", + " id 'com.diffplug.gradle.spotless'", + "}", + "spotless {", + " typescript {", + " tsfmt().tsconfigFile('tsconfig.json')", + " }", + "}"); + setFile("src/main/typescript/test.ts").toResource("npm/tsfmt/tsconfig/tsconfig.dirty"); + gradleRunner().withArguments("--stacktrace", "spotlessApply").build(); + assertFile("src/main/typescript/test.ts").sameAsResource("npm/tsfmt/tsconfig/tsconfig.clean"); + } + @Test public void usePrettier() throws IOException { setFile("build.gradle").toLines( diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md index 5cdbb26d77..c2e4a10981 100644 --- a/plugin-maven/CHANGES.md +++ b/plugin-maven/CHANGES.md @@ -3,6 +3,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`). ## [Unreleased] +### Added +* Tsfmt Maven Plugin ([#548](https://github.com/diffplug/spotless/pull/548)) ### Fixed * Eclipse-WTP formatter (web tools platform, not java) handles some character encodings incorrectly on OS with non-unicode default file encoding [#545](https://github.com/diffplug/spotless/issues/545). Fixed for Eclipse-WTP formatter Eclipse version 4.13.0 (default version). diff --git a/plugin-maven/README.md b/plugin-maven/README.md index 7e03e07eee..1e1948dea9 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -193,6 +193,56 @@ By default, all files matching `src/main/cpp/**/*.` and `src/test/cpp/**/*. ``` Use the Eclipse to define the *Code Style preferences* (see [Eclipse documentation](https://www.eclipse.org/documentation/)). Within the preferences *Edit...* dialog, you can export your configuration as XML file, which can be used as a configuration ``. If no `` is provided, the CDT default configuration is used. + + +## Applying to Typescript source + +```xml + + + + + + src/**/*.ts + + + ${basedir}/path/to/repo/tslint.json + ${basedir}/path/to/repo/tsfmt.json + ${basedir}/path/to/repo/tsconfig.json + ${basedir}/path/to/repo/vscode.json + + 1 + true + + + 7.2.2 + 3.3.3 + 5.12.1 + + + +``` + +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). See [tsfmt's default config settings](https://github.com/vvakame/typescript-formatter/blob/7764258ad42ac65071399840d1b8701868510ca7/lib/utils.ts#L11L32) for what is available. + +*Please note:* +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. + +### 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. + +```xml + + ... + /usr/bin/npm +``` + +Spotless uses npm to install necessary packages locally. It runs tsfmt using [J2V8](https://github.com/eclipsesource/J2V8) internally after that. + ## Applying to custom sources diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java index f045348117..ede8e58389 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java @@ -45,6 +45,7 @@ import com.diffplug.spotless.maven.java.Java; import com.diffplug.spotless.maven.kotlin.Kotlin; import com.diffplug.spotless.maven.scala.Scala; +import com.diffplug.spotless.maven.typescript.Typescript; public abstract class AbstractSpotlessMojo extends AbstractMojo { @@ -67,7 +68,7 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo { private File baseDir; @Parameter(defaultValue = "${project.build.directory}", required = true, readonly = true) - private File targetDir; + private File buildDir; @Parameter(defaultValue = DEFAULT_ENCODING) private String encoding; @@ -98,6 +99,9 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo { @Parameter private Cpp cpp; + @Parameter + private Typescript typescript; + /** The CSS extension is discontinued. */ @Parameter @Deprecated @@ -131,7 +135,7 @@ private List collectFiles(FormatterFactory formatterFactory) throws MojoEx Set includes = configuredIncludes.isEmpty() ? formatterFactory.defaultIncludes() : configuredIncludes; Set excludes = new HashSet<>(FileUtils.getDefaultExcludesAsList()); - excludes.add(withTrailingSeparator(targetDir.toString())); + excludes.add(withTrailingSeparator(buildDir.toString())); excludes.addAll(configuredExcludes); String includesString = String.join(",", includes); @@ -174,12 +178,12 @@ private FormatterConfig getFormatterConfig() { private FileLocator getFileLocator() { resourceManager.addSearchPath(FileResourceLoader.ID, baseDir.getAbsolutePath()); resourceManager.addSearchPath("url", ""); - resourceManager.setOutputDirectory(targetDir); - return new FileLocator(resourceManager); + resourceManager.setOutputDirectory(buildDir); + return new FileLocator(resourceManager, baseDir, buildDir); } private List getFormatterFactories() { - return Stream.concat(formats.stream(), Stream.of(java, scala, kotlin, cpp, css, xml)) + return Stream.concat(formats.stream(), Stream.of(java, scala, kotlin, cpp, typescript, css, xml)) .filter(Objects::nonNull) .collect(toList()); } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FileLocator.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FileLocator.java index 126ac4d49e..22a93d80d7 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FileLocator.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FileLocator.java @@ -18,6 +18,7 @@ import static com.diffplug.common.base.Strings.isNullOrEmpty; import java.io.File; +import java.util.Objects; import java.util.UUID; import org.codehaus.plexus.resource.ResourceManager; @@ -30,11 +31,15 @@ public class FileLocator { static final String TMP_RESOURCE_FILE_PREFIX = "spotless-resource-"; private final ResourceManager resourceManager; + private final File baseDir, buildDir; - public FileLocator(ResourceManager resourceManager) { - this.resourceManager = resourceManager; + public FileLocator(ResourceManager resourceManager, File baseDir, File buildDir) { + this.resourceManager = Objects.requireNonNull(resourceManager); + this.baseDir = Objects.requireNonNull(baseDir); + this.buildDir = Objects.requireNonNull(buildDir); } + /** Asserts that the given path is a file, then copies it with a new random name into the build folder. */ public File locateFile(String path) { if (isNullOrEmpty(path)) { return null; @@ -54,4 +59,26 @@ private static String tmpOutputFileName(String path) { String extension = FileUtils.extension(path); return TMP_RESOURCE_FILE_PREFIX + UUID.randomUUID() + '.' + extension; } + + /** Asserts that the given path exists as a file or folder. */ + public File locateLocal(String path) { + if (isNullOrEmpty(path)) { + return null; + } + + File exists = new File(path); + if (exists.exists()) { + return exists; + } + + throw new RuntimeException("Unable to locate file with path: " + path); + } + + public File getBaseDir() { + return baseDir; + } + + public File getBuildDir() { + return buildDir; + } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java index 096771c92d..bc2e5812a4 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java @@ -25,7 +25,6 @@ public class FormatterConfig { - private final File baseDir; private final String encoding; private final LineEnding lineEndings; private final Provisioner provisioner; @@ -34,7 +33,6 @@ public class FormatterConfig { public FormatterConfig(File baseDir, String encoding, LineEnding lineEndings, Provisioner provisioner, FileLocator fileLocator, List globalStepFactories) { - this.baseDir = baseDir; this.encoding = encoding; this.lineEndings = lineEndings; this.provisioner = provisioner; @@ -42,10 +40,6 @@ public FormatterConfig(File baseDir, String encoding, LineEnding lineEndings, Pr this.globalStepFactories = globalStepFactories; } - public File getBaseDir() { - return baseDir; - } - public String getEncoding() { return encoding; } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java index 0b96f07fb0..8796fa255c 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java @@ -64,7 +64,7 @@ public final Set excludes() { public final Formatter newFormatter(List filesToFormat, FormatterConfig config) { Charset formatterEncoding = encoding(config); LineEnding formatterLineEndings = lineEndings(config); - LineEnding.Policy formatterLineEndingPolicy = formatterLineEndings.createPolicy(config.getBaseDir(), () -> filesToFormat); + LineEnding.Policy formatterLineEndingPolicy = formatterLineEndings.createPolicy(config.getFileLocator().getBaseDir(), () -> filesToFormat); FormatterStepConfig stepConfig = stepConfig(formatterEncoding, config); List factories = gatherStepFactories(config.getGlobalStepFactories(), stepFactories); @@ -79,7 +79,7 @@ public final Formatter newFormatter(List filesToFormat, FormatterConfig co .lineEndingsPolicy(formatterLineEndingPolicy) .exceptionPolicy(new FormatExceptionPolicyStrict()) .steps(formatterSteps) - .rootDir(config.getBaseDir().toPath()) + .rootDir(config.getFileLocator().getBaseDir().toPath()) .build(); } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/typescript/Tsfmt.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/typescript/Tsfmt.java new file mode 100644 index 0000000000..c57350c145 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/typescript/Tsfmt.java @@ -0,0 +1,123 @@ +/* + * 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.maven.typescript; + +import java.io.File; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.apache.maven.plugins.annotations.Parameter; + +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.maven.FormatterStepConfig; +import com.diffplug.spotless.maven.FormatterStepFactory; +import com.diffplug.spotless.npm.TsConfigFileType; +import com.diffplug.spotless.npm.TsFmtFormatterStep; +import com.diffplug.spotless.npm.TypedTsFmtConfigFile; + +public class Tsfmt implements FormatterStepFactory { + + @Parameter + private String tslintFile; + + @Parameter + private String tsconfigFile; + + @Parameter + private String vscodeFile; + + @Parameter + private String tsfmtFile; + + @Parameter + private String typescriptFormatterVersion; + + @Parameter + private String typescriptVersion; + + @Parameter + private String tslintVersion; + + @Parameter + private String npmExecutable; + + @Parameter + private Map config; + + @Override + public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) { + Map devDependencies = TsFmtFormatterStep.defaultDevDependencies(); + if (typescriptFormatterVersion != null) { + devDependencies.put("typescript-formatter", typescriptFormatterVersion); + } + if (typescriptVersion != null) { + devDependencies.put("typescript", typescriptVersion); + } + if (tslintVersion != null) { + devDependencies.put("tslint", tslintVersion); + } + + File npm = npmExecutable != null ? stepConfig.getFileLocator().locateLocal(npmExecutable) : null; + + TypedTsFmtConfigFile configFile; + Map configInline; + // check that there is only 1 config file or inline config + if (this.tsconfigFile != null + ^ this.tsfmtFile != null + ^ this.tslintFile != null + ^ this.vscodeFile != null) { + if (this.config != null) { + throw onlyOneConfig(); + } + configInline = null; + if (this.tsconfigFile != null) { + configFile = new TypedTsFmtConfigFile(TsConfigFileType.TSCONFIG, stepConfig.getFileLocator().locateLocal(tsconfigFile)); + } else if (this.tsfmtFile != null) { + configFile = new TypedTsFmtConfigFile(TsConfigFileType.TSFMT, stepConfig.getFileLocator().locateLocal(tsfmtFile)); + } else if (this.tslintFile != null) { + configFile = new TypedTsFmtConfigFile(TsConfigFileType.TSLINT, stepConfig.getFileLocator().locateLocal(tslintFile)); + } else if (this.vscodeFile != null) { + configFile = new TypedTsFmtConfigFile(TsConfigFileType.VSCODE, stepConfig.getFileLocator().locateLocal(vscodeFile)); + } else { + throw new Error("Programming error: the xors did not match the cases"); + } + } else if (config != null) { + configFile = null; + configInline = new LinkedHashMap<>(); + // try to parse string values as integers or booleans + for (Map.Entry e : config.entrySet()) { + try { + configInline.put(e.getKey(), Integer.parseInt(e.getValue())); + } catch (NumberFormatException ignore) { + try { + configInline.put(e.getKey(), Boolean.parseBoolean(e.getValue())); + } catch (IllegalArgumentException ignore2) { + configInline.put(e.getKey(), e.getValue()); + } + } + } + } else { + throw onlyOneConfig(); + } + + File buildDir = stepConfig.getFileLocator().getBuildDir(); + return TsFmtFormatterStep.create(devDependencies, stepConfig.getProvisioner(), buildDir, npm, configFile, configInline); + } + + private static IllegalArgumentException onlyOneConfig() { + return new IllegalArgumentException("must specify exactly one configFile or config"); + } +} diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/typescript/Typescript.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/typescript/Typescript.java new file mode 100644 index 0000000000..e2cd953268 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/typescript/Typescript.java @@ -0,0 +1,48 @@ +/* + * 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.maven.typescript; + +import java.util.Set; + +import com.diffplug.common.collect.ImmutableSet; +import com.diffplug.spotless.maven.FormatterFactory; + +/** + * A {@link FormatterFactory} implementation that corresponds to {@code ...} configuration element. + *

+ * It defines a formatter for typescript source files. + */ +public class Typescript extends FormatterFactory { + + private static final Set DEFAULT_INCLUDES = ImmutableSet.of("src/**/*.ts"); + + private static final String LICENSE_HEADER_DELIMITER = null; + + @Override + public Set defaultIncludes() { + return DEFAULT_INCLUDES; + } + + @Override + public String licenseHeaderDelimiter() { + return LICENSE_HEADER_DELIMITER; + } + + public void addTsfmt(Tsfmt tsfmt) { + addStepFactory(tsfmt); + } + +} diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/FileLocatorTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/FileLocatorTest.java index c2c1dfe380..8b95a78fe7 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/FileLocatorTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/FileLocatorTest.java @@ -27,13 +27,22 @@ import java.nio.file.Paths; import org.codehaus.plexus.resource.ResourceManager; +import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; -public class FileLocatorTest { +import com.diffplug.spotless.ResourceHarness; - private final ResourceManager resourceManager = mock(ResourceManager.class); - private final FileLocator fileLocator = new FileLocator(resourceManager); +public class FileLocatorTest extends ResourceHarness { + + private ResourceManager resourceManager; + private FileLocator fileLocator; + + @Before + public void setup() { + resourceManager = mock(ResourceManager.class); + fileLocator = new FileLocator(resourceManager, rootFolder(), rootFolder()); + } @Test public void locateEmptyString() { diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java index 8036b1899e..13302a41a1 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java @@ -39,10 +39,18 @@ import com.github.mustachejava.Mustache; import com.github.mustachejava.MustacheFactory; +import com.diffplug.common.base.Unhandled; import com.diffplug.common.io.Resources; import com.diffplug.spotless.ResourceHarness; public class MavenIntegrationTest extends ResourceHarness { + /** + * To run tests in the IDE, run `gradlew :plugin-maven:changelogPrint`, then + * put the last version it prints into `SPOTLESS_MAVEN_VERSION_IDE`. From now + * on, if you run `gradlew :plugin-maven:runMavenBuild`, then you can run tests + * in the IDE and they will run against the results of the last `runMavenBuild` + */ + private static final String SPOTLESS_MAVEN_VERSION_IDE = null; private static final String LOCAL_MAVEN_REPOSITORY_DIR = "localMavenRepositoryDir"; private static final String SPOTLESS_MAVEN_PLUGIN_VERSION = "spotlessMavenPluginVersion"; @@ -118,6 +126,10 @@ protected void writePomWithCssSteps(String... steps) throws IOException { writePom(groupWithSteps("css", steps)); } + protected void writePomWithTypescriptSteps(String... steps) throws IOException { + writePom(groupWithSteps("typescript", steps)); + } + protected void writePom(String... configuration) throws IOException { writePom(null, configuration); } @@ -173,6 +185,15 @@ private static Map buildPomXmlParams(String[] executions, String } private static String getSystemProperty(String name) { + if (SPOTLESS_MAVEN_VERSION_IDE != null) { + if (name.equals("spotlessMavenPluginVersion")) { + return SPOTLESS_MAVEN_VERSION_IDE; + } else if (name.equals("localMavenRepositoryDir")) { + return new File("build/localMavenRepository").getAbsolutePath(); + } else { + throw Unhandled.stringException(name); + } + } String value = System.getProperty(name); if (isNullOrEmpty(value)) { fail("System property '" + name + "' is not defined"); diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/typescript/TypescriptFormatStepTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/typescript/TypescriptFormatStepTest.java new file mode 100644 index 0000000000..2a2c95a516 --- /dev/null +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/typescript/TypescriptFormatStepTest.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.maven.typescript; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; + +import org.junit.Test; + +import com.diffplug.spotless.maven.MavenIntegrationTest; +import com.diffplug.spotless.maven.MavenRunner; + +public class TypescriptFormatStepTest extends MavenIntegrationTest { + private void run(String kind) throws IOException, InterruptedException { + String path = "src/main/typescript/test.ts"; + setFile(path).toResource("npm/tsfmt/" + kind + "/" + kind + ".dirty"); + mavenRunner().withArguments("spotless:apply").runNoError(); + assertFile(path).sameAsResource("npm/tsfmt/" + kind + "/" + kind + ".clean"); + } + + @Test + public void tslint() throws Exception { + writePomWithTypescriptSteps( + "", + " ${basedir}/tslint.json", + ""); + setFile("tslint.json").toResource("npm/tsfmt/tslint/tslint.json"); + run("tslint"); + } + + @Test + public void vscode() throws Exception { + writePomWithTypescriptSteps( + "", + " ${basedir}/vscode.json", + ""); + setFile("vscode.json").toResource("npm/tsfmt/vscode/vscode.json"); + run("vscode"); + } + + @Test + public void tsfmt() throws Exception { + writePomWithTypescriptSteps( + "", + " ${basedir}/tsfmt.json", + ""); + setFile("tsfmt.json").toResource("npm/tsfmt/tsfmt/tsfmt.json"); + run("tsfmt"); + } + + @Test + public void tsfmtInline() throws Exception { + writePomWithTypescriptSteps( + "", + " ", + " 1", + " true", + " ", + ""); + run("tsfmt"); + } + + @Test + public void tsconfig() throws Exception { + writePomWithTypescriptSteps( + "", + " ${project.basedir}/tsconfig.json", + ""); + setFile("tsconfig.json").toResource("npm/tsfmt/tsconfig/tsconfig.json"); + run("tsconfig"); + } + + @Test + public void testTypescript_2_Configs() throws Exception { + writePomWithTypescriptSteps( + "", + " ${basedir}/tslint.json", + " ${basedir}/tslint.json", + ""); + setFile("vscode.json").toResource("npm/tsfmt/vscode/vscode.json"); + setFile("tsfmt.json").toResource("npm/tsfmt/tsfmt/tsfmt.json"); + + String path = "src/main/typescript/test.ts"; + setFile(path).toResource("npm/tsfmt/tsfmt/tsfmt.dirty"); + MavenRunner.Result result = mavenRunner().withArguments("spotless:apply").runHasError(); + assertThat(result.output()).contains("must specify exactly one configFile or config"); + } +} diff --git a/testlib/src/main/resources/npm/tsfmt/tsconfig/tsconfig.json b/testlib/src/main/resources/npm/tsfmt/tsconfig/tsconfig.json index 4b233e423e..bc7da8603f 100644 --- a/testlib/src/main/resources/npm/tsfmt/tsconfig/tsconfig.json +++ b/testlib/src/main/resources/npm/tsfmt/tsconfig/tsconfig.json @@ -1,4 +1,8 @@ { - // comment - /* comment */ + "include": [ + "src/main/typescript/*.ts" + ], + "exclude": [ + "nothing.xml" + ] }