Skip to content

Commit 7ba6d1a

Browse files
authored
Merge pull request #553 from source-knights/master
tsfmt maven plugin
2 parents 64849c8 + 1bb33d6 commit 7ba6d1a

File tree

15 files changed

+428
-28
lines changed

15 files changed

+428
-28
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ extra('java.EclipseFormatterStep') +'{{yes}} | {{yes}}
4747
lib('kotlin.KtLintStep') +'{{yes}} | {{yes}} | {{no}} |',
4848
lib('markdown.FreshMarkStep') +'{{yes}} | {{no}} | {{no}} |',
4949
lib('npm.PrettierFormatterStep') +'{{yes}} | {{no}} | {{no}} |',
50-
lib('npm.TsFmtFormatterStep') +'{{yes}} | {{no}} | {{no}} |',
50+
lib('npm.TsFmtFormatterStep') +'{{yes}} | {{yes}} | {{no}} |',
5151
lib('scala.ScalaFmtStep') +'{{yes}} | {{yes}} | {{no}} |',
5252
lib('sql.DBeaverSQLFormatterStep') +'{{yes}} | {{no}} | {{no}} |',
5353
extra('wtp.EclipseWtpFormatterStep') +'{{yes}} | {{yes}} | {{no}} |',
@@ -74,7 +74,7 @@ extra('wtp.EclipseWtpFormatterStep') +'{{yes}} | {{yes}}
7474
| [`kotlin.KtLintStep`](lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java) | :+1: | :+1: | :white_large_square: |
7575
| [`markdown.FreshMarkStep`](lib/src/main/java/com/diffplug/spotless/markdown/FreshMarkStep.java) | :+1: | :white_large_square: | :white_large_square: |
7676
| [`npm.PrettierFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/PrettierFormatterStep.java) | :+1: | :white_large_square: | :white_large_square: |
77-
| [`npm.TsFmtFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java) | :+1: | :white_large_square: | :white_large_square: |
77+
| [`npm.TsFmtFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java) | :+1: | :+1: | :white_large_square: |
7878
| [`scala.ScalaFmtStep`](lib/src/main/java/com/diffplug/spotless/scala/ScalaFmtStep.java) | :+1: | :+1: | :white_large_square: |
7979
| [`sql.DBeaverSQLFormatterStep`](lib/src/main/java/com/diffplug/spotless/sql/DBeaverSQLFormatterStep.java) | :+1: | :white_large_square: | :white_large_square: |
8080
| [`wtp.EclipseWtpFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/wtp/EclipseWtpFormatterStep.java) | :+1: | :+1: | :white_large_square: |

lib/src/main/java/com/diffplug/spotless/npm/NodeJSWrapper.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import java.util.Objects;
2121
import java.util.concurrent.atomic.AtomicBoolean;
2222

23+
import com.diffplug.spotless.LineEnding;
24+
2325
class NodeJSWrapper extends ReflectiveObjectWrapper {
2426

2527
public static final String V8_RUNTIME_CLASS = "com.eclipsesource.v8.V8";
@@ -33,7 +35,7 @@ public NodeJSWrapper(ClassLoader classLoader) {
3335
super(Reflective.withClassLoader(classLoader),
3436
reflective -> {
3537
final boolean firstRun = flagsSet.compareAndSet(false, true);
36-
if (firstRun) {
38+
if (firstRun && LineEnding.PLATFORM_NATIVE.str().equals("\r\n")) {
3739
reflective.invokeStaticMethod(V8_RUNTIME_CLASS, "setFlags", "-color=false"); // required to run prettier on windows
3840
}
3941
return reflective.invokeStaticMethod(WRAPPED_CLASS, "createNodeJS");

plugin-gradle/src/test/java/com/diffplug/gradle/spotless/TypescriptExtensionTest.java

+19-5
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,7 @@ public void useTsfmtInlineConfig() throws IOException {
8989

9090
@Test
9191
public void useTsfmtFileConfig() throws IOException {
92-
setFile("tsfmt.json").toLines(
93-
"{",
94-
" \"indentSize\": 1,",
95-
" \"convertTabsToSpaces\": true",
96-
"}");
92+
setFile("tsfmt.json").toResource("npm/tsfmt/tsfmt/tsfmt.json");
9793
setFile("build.gradle").toLines(
9894
"buildscript { repositories { mavenCentral() } }",
9995
"plugins {",
@@ -110,6 +106,24 @@ public void useTsfmtFileConfig() throws IOException {
110106
assertFile("test.ts").sameAsResource("npm/tsfmt/tsfmt/tsfmt.clean");
111107
}
112108

109+
@Test
110+
public void useTsConfigFileConfig() throws IOException {
111+
setFile("tsconfig.json").toResource("npm/tsfmt/tsconfig/tsconfig.json");
112+
setFile("build.gradle").toLines(
113+
"buildscript { repositories { mavenCentral() } }",
114+
"plugins {",
115+
" id 'com.diffplug.gradle.spotless'",
116+
"}",
117+
"spotless {",
118+
" typescript {",
119+
" tsfmt().tsconfigFile('tsconfig.json')",
120+
" }",
121+
"}");
122+
setFile("src/main/typescript/test.ts").toResource("npm/tsfmt/tsconfig/tsconfig.dirty");
123+
gradleRunner().withArguments("--stacktrace", "spotlessApply").build();
124+
assertFile("src/main/typescript/test.ts").sameAsResource("npm/tsfmt/tsconfig/tsconfig.clean");
125+
}
126+
113127
@Test
114128
public void usePrettier() throws IOException {
115129
setFile("build.gradle").toLines(

plugin-maven/CHANGES.md

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).
44

55
## [Unreleased]
6+
### Added
7+
* Tsfmt Maven Plugin ([#548](https://github.com/diffplug/spotless/pull/548))
68
### Fixed
79
* 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).
810

plugin-maven/README.md

+50
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,56 @@ By default, all files matching `src/main/cpp/**/*.<ext>` and `src/test/cpp/**/*.
193193
```
194194
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 `<file>`. If no `<file>` is provided, the CDT default configuration is used.
195195

196+
<a name="typescript"></a>
197+
198+
## Applying to Typescript source
199+
200+
```xml
201+
<configuration>
202+
<typescript>
203+
<tsfmt>
204+
<!-- optionally define which files will be formatted. -->
205+
<includes>
206+
<include>src/**/*.ts</include> <!-- default value if nothing is specified -->
207+
</includes>
208+
<!-- must specify exactly one of the following "{foo}File" or "config" elements -->
209+
<tslintFile>${basedir}/path/to/repo/tslint.json</tslintFile>
210+
<tsfmtFile>${basedir}/path/to/repo/tsfmt.json</tsfmtFile>
211+
<tsconfigFile>${basedir}/path/to/repo/tsconfig.json</tsconfigFile>
212+
<vscodeFile>${basedir}/path/to/repo/vscode.json</vscodeFile>
213+
<config>
214+
<indentSize>1</indentSize>
215+
<convertTabsToSpaces>true</convertTabsToSpaces>
216+
</config>
217+
<!-- optionally configure following versions to use, shown values are defaults-->
218+
<typescriptFormatterVersion>7.2.2</typescriptFormatterVersion>
219+
<typescriptVersion>3.3.3</typescriptVersion>
220+
<tslintVersion>5.12.1</tslintVersion>
221+
</tsfmt>
222+
</typescript>
223+
</configuration>
224+
```
225+
226+
Supported config file types are `tsconfigFile`, `tslintFile`, `vscodeFile` and `tsfmtFile`. They are corresponding to the respective
227+
[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.
228+
229+
*Please note:*
230+
The auto-discovery of config files (up the file tree) will not work when using tsfmt within spotless,
231+
hence you are required to provide resolvable file paths for config files.
232+
233+
### Prerequisite: tsfmt requires a working NodeJS version
234+
235+
tsfmt is based on NodeJS, so to use it, a working NodeJS installation (especially npm) is required on the host running spotless.
236+
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.
237+
238+
```xml
239+
<configuration><typescript><tsfmt>
240+
...
241+
<npmExecutable>/usr/bin/npm</npmExecutable>
242+
```
243+
244+
Spotless uses npm to install necessary packages locally. It runs tsfmt using [J2V8](https://github.com/eclipsesource/J2V8) internally after that.
245+
196246
<a name="format"></a>
197247

198248
## Applying to custom sources

plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java

+9-5
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import com.diffplug.spotless.maven.java.Java;
4646
import com.diffplug.spotless.maven.kotlin.Kotlin;
4747
import com.diffplug.spotless.maven.scala.Scala;
48+
import com.diffplug.spotless.maven.typescript.Typescript;
4849

4950
public abstract class AbstractSpotlessMojo extends AbstractMojo {
5051

@@ -67,7 +68,7 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo {
6768
private File baseDir;
6869

6970
@Parameter(defaultValue = "${project.build.directory}", required = true, readonly = true)
70-
private File targetDir;
71+
private File buildDir;
7172

7273
@Parameter(defaultValue = DEFAULT_ENCODING)
7374
private String encoding;
@@ -98,6 +99,9 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo {
9899
@Parameter
99100
private Cpp cpp;
100101

102+
@Parameter
103+
private Typescript typescript;
104+
101105
/** The CSS extension is discontinued. */
102106
@Parameter
103107
@Deprecated
@@ -131,7 +135,7 @@ private List<File> collectFiles(FormatterFactory formatterFactory) throws MojoEx
131135
Set<String> includes = configuredIncludes.isEmpty() ? formatterFactory.defaultIncludes() : configuredIncludes;
132136

133137
Set<String> excludes = new HashSet<>(FileUtils.getDefaultExcludesAsList());
134-
excludes.add(withTrailingSeparator(targetDir.toString()));
138+
excludes.add(withTrailingSeparator(buildDir.toString()));
135139
excludes.addAll(configuredExcludes);
136140

137141
String includesString = String.join(",", includes);
@@ -174,12 +178,12 @@ private FormatterConfig getFormatterConfig() {
174178
private FileLocator getFileLocator() {
175179
resourceManager.addSearchPath(FileResourceLoader.ID, baseDir.getAbsolutePath());
176180
resourceManager.addSearchPath("url", "");
177-
resourceManager.setOutputDirectory(targetDir);
178-
return new FileLocator(resourceManager);
181+
resourceManager.setOutputDirectory(buildDir);
182+
return new FileLocator(resourceManager, baseDir, buildDir);
179183
}
180184

181185
private List<FormatterFactory> getFormatterFactories() {
182-
return Stream.concat(formats.stream(), Stream.of(java, scala, kotlin, cpp, css, xml))
186+
return Stream.concat(formats.stream(), Stream.of(java, scala, kotlin, cpp, typescript, css, xml))
183187
.filter(Objects::nonNull)
184188
.collect(toList());
185189
}

plugin-maven/src/main/java/com/diffplug/spotless/maven/FileLocator.java

+29-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static com.diffplug.common.base.Strings.isNullOrEmpty;
1919

2020
import java.io.File;
21+
import java.util.Objects;
2122
import java.util.UUID;
2223

2324
import org.codehaus.plexus.resource.ResourceManager;
@@ -30,11 +31,15 @@ public class FileLocator {
3031
static final String TMP_RESOURCE_FILE_PREFIX = "spotless-resource-";
3132

3233
private final ResourceManager resourceManager;
34+
private final File baseDir, buildDir;
3335

34-
public FileLocator(ResourceManager resourceManager) {
35-
this.resourceManager = resourceManager;
36+
public FileLocator(ResourceManager resourceManager, File baseDir, File buildDir) {
37+
this.resourceManager = Objects.requireNonNull(resourceManager);
38+
this.baseDir = Objects.requireNonNull(baseDir);
39+
this.buildDir = Objects.requireNonNull(buildDir);
3640
}
3741

42+
/** Asserts that the given path is a file, then copies it with a new random name into the build folder. */
3843
public File locateFile(String path) {
3944
if (isNullOrEmpty(path)) {
4045
return null;
@@ -54,4 +59,26 @@ private static String tmpOutputFileName(String path) {
5459
String extension = FileUtils.extension(path);
5560
return TMP_RESOURCE_FILE_PREFIX + UUID.randomUUID() + '.' + extension;
5661
}
62+
63+
/** Asserts that the given path exists as a file or folder. */
64+
public File locateLocal(String path) {
65+
if (isNullOrEmpty(path)) {
66+
return null;
67+
}
68+
69+
File exists = new File(path);
70+
if (exists.exists()) {
71+
return exists;
72+
}
73+
74+
throw new RuntimeException("Unable to locate file with path: " + path);
75+
}
76+
77+
public File getBaseDir() {
78+
return baseDir;
79+
}
80+
81+
public File getBuildDir() {
82+
return buildDir;
83+
}
5784
}

plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java

-6
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
public class FormatterConfig {
2727

28-
private final File baseDir;
2928
private final String encoding;
3029
private final LineEnding lineEndings;
3130
private final Provisioner provisioner;
@@ -34,18 +33,13 @@ public class FormatterConfig {
3433

3534
public FormatterConfig(File baseDir, String encoding, LineEnding lineEndings, Provisioner provisioner,
3635
FileLocator fileLocator, List<FormatterStepFactory> globalStepFactories) {
37-
this.baseDir = baseDir;
3836
this.encoding = encoding;
3937
this.lineEndings = lineEndings;
4038
this.provisioner = provisioner;
4139
this.fileLocator = fileLocator;
4240
this.globalStepFactories = globalStepFactories;
4341
}
4442

45-
public File getBaseDir() {
46-
return baseDir;
47-
}
48-
4943
public String getEncoding() {
5044
return encoding;
5145
}

plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public final Set<String> excludes() {
6464
public final Formatter newFormatter(List<File> filesToFormat, FormatterConfig config) {
6565
Charset formatterEncoding = encoding(config);
6666
LineEnding formatterLineEndings = lineEndings(config);
67-
LineEnding.Policy formatterLineEndingPolicy = formatterLineEndings.createPolicy(config.getBaseDir(), () -> filesToFormat);
67+
LineEnding.Policy formatterLineEndingPolicy = formatterLineEndings.createPolicy(config.getFileLocator().getBaseDir(), () -> filesToFormat);
6868

6969
FormatterStepConfig stepConfig = stepConfig(formatterEncoding, config);
7070
List<FormatterStepFactory> factories = gatherStepFactories(config.getGlobalStepFactories(), stepFactories);
@@ -79,7 +79,7 @@ public final Formatter newFormatter(List<File> filesToFormat, FormatterConfig co
7979
.lineEndingsPolicy(formatterLineEndingPolicy)
8080
.exceptionPolicy(new FormatExceptionPolicyStrict())
8181
.steps(formatterSteps)
82-
.rootDir(config.getBaseDir().toPath())
82+
.rootDir(config.getFileLocator().getBaseDir().toPath())
8383
.build();
8484
}
8585

0 commit comments

Comments
 (0)