Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for prettier 3+ #1760

Merged
merged 13 commits into from
Jul 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ This document is intended for Spotless developers.
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).

## [Unreleased]
### Fixed
* Add support for `prettier` version `3.0.0` and newer. ([#1760]https://github.com/diffplug/spotless/pull/1760), [#1751](https://github.com/diffplug/spotless/issues/1751))
* Fix npm install calls when npm cache is not up-to-date. ([#1760]https://github.com/diffplug/spotless/pull/1760), [#1750](https://github.com/diffplug/spotless/issues/1750))
### Changes
* Bump default `prettier` version to latest (v2) `2.8.1` -> `2.8.8`. ([#1760](https://github.com/diffplug/spotless/pull/1760))

## [2.40.0] - 2023-07-17
### Added
Expand Down
29 changes: 28 additions & 1 deletion lib/src/main/java/com/diffplug/spotless/npm/NodeApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,18 @@
*/
package com.diffplug.spotless.npm;

import static com.diffplug.spotless.npm.NpmProcessFactory.OnlinePreferrence.PREFER_OFFLINE;
import static com.diffplug.spotless.npm.NpmProcessFactory.OnlinePreferrence.PREFER_ONLINE;

import java.util.Objects;

import javax.annotation.Nonnull;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.diffplug.spotless.ProcessRunner;

public class NodeApp {

private static final Logger logger = LoggerFactory.getLogger(NodeApp.class);
Expand Down Expand Up @@ -83,6 +88,28 @@ void prepareNodeAppLayout() {

void npmInstall() {
timedLogger.withInfo("Installing npm dependencies for {} with {}.", this.nodeServerLayout, this.npmProcessFactory.describe())
.run(() -> npmProcessFactory.createNpmInstallProcess(nodeServerLayout, formatterStepLocations).waitFor());
.run(this::optimizedNpmInstall);
}

private void optimizedNpmInstall() {
try {
npmProcessFactory.createNpmInstallProcess(nodeServerLayout, formatterStepLocations, PREFER_OFFLINE).waitFor();
} catch (NpmProcessException e) {
if (!offlineInstallFailed(e.getResult())) {
throw e; // pass through
}
// if the npm install fails with message "No matching version found for <package>@<version>", we try again without the offline flag
npmProcessFactory.createNpmInstallProcess(nodeServerLayout, formatterStepLocations, PREFER_ONLINE).waitFor();
}
}

private boolean offlineInstallFailed(ProcessRunner.Result result) {
if (result == null) {
return false; // no result, something else must have happened
}
if (result.exitCode() == 0) {
return false; // all is well
}
return result.stdOutUtf8().contains("code ETARGET") && result.stdOutUtf8().contains("No matching version found for"); // offline install failed, needs online install
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ public static NodeModulesCachingNpmProcessFactory create(@Nonnull File cacheDir)
}

@Override
public NpmProcess createNpmInstallProcess(NodeServerLayout nodeServerLayout, NpmFormatterStepLocations formatterStepLocations) {
NpmProcess actualNpmInstallProcess = StandardNpmProcessFactory.INSTANCE.createNpmInstallProcess(nodeServerLayout, formatterStepLocations);
public NpmProcess createNpmInstallProcess(NodeServerLayout nodeServerLayout, NpmFormatterStepLocations formatterStepLocations, OnlinePreferrence onlinePreferrence) {
NpmProcess actualNpmInstallProcess = StandardNpmProcessFactory.INSTANCE.createNpmInstallProcess(nodeServerLayout, formatterStepLocations, onlinePreferrence);
return new CachingNmpInstall(actualNpmInstallProcess, nodeServerLayout);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,26 @@
*/
package com.diffplug.spotless.npm;

import javax.annotation.CheckForNull;

import com.diffplug.spotless.ProcessRunner;

public class NpmProcessException extends RuntimeException {
private static final long serialVersionUID = 6424331316676759525L;
private final transient ProcessRunner.Result result;

public NpmProcessException(String message) {
public NpmProcessException(String message, ProcessRunner.Result result) {
super(message);
this.result = result;
}

public NpmProcessException(String message, Throwable cause) {
super(message, cause);
this.result = null;
}

@CheckForNull
public ProcessRunner.Result getResult() {
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,22 @@
package com.diffplug.spotless.npm;

public interface NpmProcessFactory {
NpmProcess createNpmInstallProcess(NodeServerLayout nodeServerLayout, NpmFormatterStepLocations formatterStepLocations);

enum OnlinePreferrence {
PREFER_OFFLINE("--prefer-offline"), PREFER_ONLINE("--prefer-online");

private final String option;

OnlinePreferrence(String option) {
this.option = option;
}

public String option() {
return option;
}
}

NpmProcess createNpmInstallProcess(NodeServerLayout nodeServerLayout, NpmFormatterStepLocations formatterStepLocations, OnlinePreferrence onlinePreferrence);

NpmLongRunningProcess createNpmServeProcess(NodeServerLayout nodeServerLayout, NpmFormatterStepLocations formatterStepLocations);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ public class PrettierFormatterStep {

public static final String NAME = "prettier-format";

public static final String DEFAULT_VERSION = "2.8.8";

public static final Map<String, String> defaultDevDependencies() {
return defaultDevDependenciesWithPrettier("2.8.1");
return defaultDevDependenciesWithPrettier(DEFAULT_VERSION);
}

public static final Map<String, String> defaultDevDependenciesWithPrettier(String version) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ private StandardNpmProcessFactory() {
}

@Override
public NpmProcess createNpmInstallProcess(NodeServerLayout nodeServerLayout, NpmFormatterStepLocations formatterStepLocations) {
return new NpmInstall(nodeServerLayout.nodeModulesDir(), formatterStepLocations);
public NpmProcess createNpmInstallProcess(NodeServerLayout nodeServerLayout, NpmFormatterStepLocations formatterStepLocations, OnlinePreferrence onlinePreferrence) {
return new NpmInstall(nodeServerLayout.nodeModulesDir(), formatterStepLocations, onlinePreferrence);
}

@Override
Expand Down Expand Up @@ -80,8 +80,11 @@ public String doDescribe() {

private static class NpmInstall extends AbstractStandardNpmProcess implements NpmProcess {

public NpmInstall(File workingDir, NpmFormatterStepLocations formatterStepLocations) {
private final OnlinePreferrence onlinePreferrence;

public NpmInstall(File workingDir, NpmFormatterStepLocations formatterStepLocations, OnlinePreferrence onlinePreferrence) {
super(workingDir, formatterStepLocations);
this.onlinePreferrence = onlinePreferrence;
}

@Override
Expand All @@ -91,7 +94,7 @@ protected List<String> commandLine() {
"install",
"--no-audit",
"--no-fund",
"--prefer-offline");
onlinePreferrence.option());
}

@Override
Expand All @@ -103,7 +106,7 @@ public String describe() {
public ProcessRunner.Result waitFor() {
try (ProcessRunner.LongRunningProcess npmProcess = doStart()) {
if (npmProcess.waitFor() != 0) {
throw new NpmProcessException("Running npm command '" + describe() + "' failed with exit code: " + npmProcess.exitValue() + "\n\n" + npmProcess.result());
throw new NpmProcessException("Running npm command '" + describe() + "' failed with exit code: " + npmProcess.exitValue() + "\n\n" + npmProcess.result(), npmProcess.result());
}
return npmProcess.result();
} catch (InterruptedException e) {
Expand Down
46 changes: 29 additions & 17 deletions lib/src/main/resources/com/diffplug/spotless/npm/prettier-serve.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
const prettier = require("prettier");

app.post("/prettier/config-options", (req, res) => {
var config_data = req.body;
var prettier_config_path = config_data.prettier_config_path;
var prettier_config_options = config_data.prettier_config_options || {};
const config_data = req.body;
const prettier_config_path = config_data.prettier_config_path;
const prettier_config_options = config_data.prettier_config_options || {};

if (prettier_config_path) {
prettier
.resolveConfig(undefined, { config: prettier_config_path })
.then(options => {
var mergedConfigOptions = mergeConfigOptions(options, prettier_config_options);
const mergedConfigOptions = mergeConfigOptions(options, prettier_config_options);
res.set("Content-Type", "application/json")
res.json(mergedConfigOptions);
})
Expand All @@ -20,12 +20,12 @@ app.post("/prettier/config-options", (req, res) => {
res.json(prettier_config_options);
});

app.post("/prettier/format", (req, res) => {
var format_data = req.body;
app.post("/prettier/format", async (req, res) => {
const format_data = req.body;

var formatted_file_content = "";
let formatted_file_content = "";
try {
formatted_file_content = prettier.format(format_data.file_content, format_data.config_options);
formatted_file_content = await prettierFormat(format_data.file_content, format_data.config_options);
} catch(err) {
res.status(500).send("Error while formatting: " + err);
return;
Expand All @@ -34,7 +34,20 @@ app.post("/prettier/format", (req, res) => {
res.send(formatted_file_content);
});

var mergeConfigOptions = function(resolved_config_options, config_options) {
const prettierFormat = async function(file_content, config_options) {
const result = prettier.format(file_content, config_options);

// Check if result is a Promise (version 3.0.0 and above)
if (typeof result.then === 'function') {
return result;
}

// If it's not a Promise (meaning it's a string), wrap it in a Promise (< 3.0.0)
return Promise.resolve(result);
}


const mergeConfigOptions = function(resolved_config_options, config_options) {
if (resolved_config_options !== undefined && config_options !== undefined) {
return extend(resolved_config_options, config_options);
}
Expand All @@ -46,15 +59,15 @@ var mergeConfigOptions = function(resolved_config_options, config_options) {
}
};

var extend = function() {
const extend = function() {
// Variables
var extended = {};
var i = 0;
var length = arguments.length;
const extended = {};
let i = 0;
const length = arguments.length;

// Merge the object into the extended object
var merge = function(obj) {
for (var prop in obj) {
const merge = function (obj) {
for (const prop in obj) {
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
extended[prop] = obj[prop];
}
Expand All @@ -63,9 +76,8 @@ var extend = function() {

// Loop through each object and conduct a merge
for (; i < length; i++) {
var obj = arguments[i];
const obj = arguments[i];
merge(obj);
}

return extended;
};
6 changes: 5 additions & 1 deletion plugin-gradle/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `3.27.0`).

## [Unreleased]
### Fixed
* Add support for `prettier` version `3.0.0` and newer. ([#1760]https://github.com/diffplug/spotless/pull/1760), [#1751](https://github.com/diffplug/spotless/issues/1751))
* Fix npm install calls when npm cache is not up-to-date. ([#1760]https://github.com/diffplug/spotless/pull/1760), [#1750](https://github.com/diffplug/spotless/issues/1750))
### Changes
* Bump default `prettier` version to latest (v2) `2.8.1` -> `2.8.8`. ([#1760](https://github.com/diffplug/spotless/pull/1760))

## [6.20.0] - 2023-07-17
### Added
Expand All @@ -23,7 +28,6 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
* Bump default `ktlint` version to latest `0.49.1` -> `0.50.0`. ([#1741](https://github.com/diffplug/spotless/issues/1741))
* Dropped support for `ktlint 0.47.x` following our policy of supporting two breaking changes at a time.
* Dropped support for deprecated `useExperimental` parameter in favor of the `ktlint_experimental` property.

## [6.19.0] - 2023-05-24
### Added
* Support Rome as a formatter for JavaScript and TypeScript code. Adds a new `rome` step to `javascript` and `typescript` formatter configurations. ([#1663](https://github.com/diffplug/spotless/pull/1663))
Expand Down
5 changes: 3 additions & 2 deletions plugin-gradle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,7 @@ spotless {
yaml {
target 'src/**/*.yaml' // you have to set the target manually
jackson() // has its own section below
prettier() // has its own section below
}
}
```
Expand Down Expand Up @@ -978,11 +979,11 @@ Since spotless uses the actual npm prettier package behind the scenes, it is pos
```gradle
spotless {
java {
prettier(['prettier': '2.0.5', 'prettier-plugin-java': '0.8.0']).config(['parser': 'java', 'tabWidth': 4])
prettier(['prettier': '2.8.8', 'prettier-plugin-java': '2.2.0']).config(['parser': 'java', 'tabWidth': 4])
}
format 'php', {
target 'src/**/*.php'
prettier(['prettier': '2.0.5', '@prettier/plugin-php': '0.14.2']).config(['parser': 'php', 'tabWidth': 3])
prettier(['prettier': '2.8.8', '@prettier/plugin-php': '0.19.6']).config(['parser': 'php', 'tabWidth': 3])
}
}
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ private BuildResult runPhpPrettierOnDir(File projDir, File cacheDir) throws IOEx
"prettierConfig['tabWidth'] = 3",
"prettierConfig['parser'] = 'php'",
"def prettierPackages = [:]",
"prettierPackages['prettier'] = '2.0.5'",
"prettierPackages['@prettier/plugin-php'] = '0.14.2'",
"prettierPackages['prettier'] = '2.8.8'",
"prettierPackages['@prettier/plugin-php'] = '0.19.6'",
"spotless {",
" format 'php', {",
" target 'php-example.php'",
Expand Down
Loading
Loading