Skip to content

Commit

Permalink
Merge pull request #553 from source-knights/master
Browse files Browse the repository at this point in the history
tsfmt maven plugin
  • Loading branch information
nedtwigg committed Apr 2, 2020
2 parents 64849c8 + 1bb33d6 commit 7ba6d1a
Show file tree
Hide file tree
Showing 15 changed files with 428 additions and 28 deletions.
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -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}} |',
Expand All @@ -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: |
Expand Down
Expand Up @@ -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";
Expand All @@ -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");
Expand Down
Expand Up @@ -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 {",
Expand All @@ -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(
Expand Down
2 changes: 2 additions & 0 deletions plugin-maven/CHANGES.md
Expand Up @@ -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).

Expand Down
50 changes: 50 additions & 0 deletions plugin-maven/README.md
Expand Up @@ -193,6 +193,56 @@ By default, all files matching `src/main/cpp/**/*.<ext>` 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 `<file>`. If no `<file>` is provided, the CDT default configuration is used.

<a name="typescript"></a>

## Applying to Typescript source

```xml
<configuration>
<typescript>
<tsfmt>
<!-- optionally define which files will be formatted. -->
<includes>
<include>src/**/*.ts</include> <!-- default value if nothing is specified -->
</includes>
<!-- must specify exactly one of the following "{foo}File" or "config" elements -->
<tslintFile>${basedir}/path/to/repo/tslint.json</tslintFile>
<tsfmtFile>${basedir}/path/to/repo/tsfmt.json</tsfmtFile>
<tsconfigFile>${basedir}/path/to/repo/tsconfig.json</tsconfigFile>
<vscodeFile>${basedir}/path/to/repo/vscode.json</vscodeFile>
<config>
<indentSize>1</indentSize>
<convertTabsToSpaces>true</convertTabsToSpaces>
</config>
<!-- optionally configure following versions to use, shown values are defaults-->
<typescriptFormatterVersion>7.2.2</typescriptFormatterVersion>
<typescriptVersion>3.3.3</typescriptVersion>
<tslintVersion>5.12.1</tslintVersion>
</tsfmt>
</typescript>
</configuration>
```

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
<configuration><typescript><tsfmt>
...
<npmExecutable>/usr/bin/npm</npmExecutable>
```

Spotless uses npm to install necessary packages locally. It runs tsfmt using [J2V8](https://github.com/eclipsesource/J2V8) internally after that.

<a name="format"></a>

## Applying to custom sources
Expand Down
Expand Up @@ -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 {

Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -131,7 +135,7 @@ private List<File> collectFiles(FormatterFactory formatterFactory) throws MojoEx
Set<String> includes = configuredIncludes.isEmpty() ? formatterFactory.defaultIncludes() : configuredIncludes;

Set<String> excludes = new HashSet<>(FileUtils.getDefaultExcludesAsList());
excludes.add(withTrailingSeparator(targetDir.toString()));
excludes.add(withTrailingSeparator(buildDir.toString()));
excludes.addAll(configuredExcludes);

String includesString = String.join(",", includes);
Expand Down Expand Up @@ -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<FormatterFactory> 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());
}
Expand Down
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
}
}
Expand Up @@ -25,7 +25,6 @@

public class FormatterConfig {

private final File baseDir;
private final String encoding;
private final LineEnding lineEndings;
private final Provisioner provisioner;
Expand All @@ -34,18 +33,13 @@ public class FormatterConfig {

public FormatterConfig(File baseDir, String encoding, LineEnding lineEndings, Provisioner provisioner,
FileLocator fileLocator, List<FormatterStepFactory> globalStepFactories) {
this.baseDir = baseDir;
this.encoding = encoding;
this.lineEndings = lineEndings;
this.provisioner = provisioner;
this.fileLocator = fileLocator;
this.globalStepFactories = globalStepFactories;
}

public File getBaseDir() {
return baseDir;
}

public String getEncoding() {
return encoding;
}
Expand Down
Expand Up @@ -64,7 +64,7 @@ public final Set<String> excludes() {
public final Formatter newFormatter(List<File> 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<FormatterStepFactory> factories = gatherStepFactories(config.getGlobalStepFactories(), stepFactories);
Expand All @@ -79,7 +79,7 @@ public final Formatter newFormatter(List<File> filesToFormat, FormatterConfig co
.lineEndingsPolicy(formatterLineEndingPolicy)
.exceptionPolicy(new FormatExceptionPolicyStrict())
.steps(formatterSteps)
.rootDir(config.getBaseDir().toPath())
.rootDir(config.getFileLocator().getBaseDir().toPath())
.build();
}

Expand Down

0 comments on commit 7ba6d1a

Please sign in to comment.