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

Support editorconfig file for prettier #2364

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
10 changes: 9 additions & 1 deletion lib/src/main/java/com/diffplug/spotless/npm/PrettierConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@ public class PrettierConfig implements Serializable {

private final TreeMap<String, Object> options;

public PrettierConfig(@Nullable File prettierConfigPath, @Nullable Map<String, Object> options) {
private final Boolean editorconfig;

public PrettierConfig(@Nullable File prettierConfigPath, @Nullable Map<String, Object> options, @Nullable Boolean editorconfig) {
this.prettierConfigPathSignature = prettierConfigPath == null ? null : FileSignature.promise(prettierConfigPath);
this.options = options == null ? new TreeMap<>() : new TreeMap<>(options);
this.editorconfig = editorconfig;
}

@Nullable
Expand All @@ -45,4 +48,9 @@ public File getPrettierConfigPath() {
public Map<String, Object> getOptions() {
return new TreeMap<>(this.options);
}

@Nullable
public Boolean getEditorconfig() {
return editorconfig;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public FormatterFunc createFormatterFunc() {
logger.info("creating formatter function (starting server)");
ServerProcessInfo prettierRestServer = toRuntime().npmRunServer();
PrettierRestService restService = new PrettierRestService(prettierRestServer.getBaseUrl());
String prettierConfigOptions = restService.resolveConfig(this.prettierConfig.getPrettierConfigPath(), this.prettierConfig.getOptions());
String prettierConfigOptions = restService.resolveConfig(this.prettierConfig.getPrettierConfigPath(), this.prettierConfig.getOptions(), prettierConfig.getEditorconfig());
return Closeable.ofDangerous(() -> endServer(restService, prettierRestServer), new PrettierFilePathPassingFormatterFunc(prettierConfigOptions, restService));
} catch (IOException e) {
throw ThrowingEx.asRuntime(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,17 @@ public class PrettierRestService extends BaseNpmRestService {
super(baseUrl);
}

public String resolveConfig(File prettierConfigPath, Map<String, Object> prettierConfigOptions) {
public String resolveConfig(File prettierConfigPath, Map<String, Object> prettierConfigOptions, Boolean editorconfig) {
Map<String, Object> jsonProperties = new LinkedHashMap<>();
if (prettierConfigPath != null) {
jsonProperties.put("prettier_config_path", prettierConfigPath.getAbsolutePath());
}
if (prettierConfigOptions != null) {
jsonProperties.put("prettier_config_options", JsonWriter.of(prettierConfigOptions).toJsonRawValue());
}
if (editorconfig != null) {
jsonProperties.put("editorconfig", editorconfig);
}
return restClient.postJson("/prettier/config-options", jsonProperties);
}

Expand Down
21 changes: 8 additions & 13 deletions lib/src/main/resources/com/diffplug/spotless/npm/prettier-serve.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,14 @@ app.post("/prettier/config-options", (req, res) => {
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 => {
const mergedConfigOptions = mergeConfigOptions(options, prettier_config_options);
res.set("Content-Type", "application/json")
res.json(mergedConfigOptions);
})
.catch(reason => res.status(501).send("Exception while resolving config_file_path: " + reason));
return;
}
res.set("Content-Type", "application/json")
res.json(prettier_config_options);
prettier
.resolveConfig(prettier_config_path, { editorconfig: config_data.editorconfig })
.then(options => {
const mergedConfigOptions = mergeConfigOptions(options, prettier_config_options);
res.set("Content-Type", "application/json")
res.json(mergedConfigOptions);
})
.catch(reason => res.status(501).send("Exception while resolving config_file_path: " + reason));
});

app.post("/prettier/format", async (req, res) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,9 @@ public class PrettierConfig extends NpmStepConfig<PrettierConfig> {
@Nullable
Map<String, Object> prettierConfig;

@Nullable
Boolean editorconfig;

final Map<String, String> devDependencies;

PrettierConfig(Map<String, String> devDependencies) {
Expand All @@ -788,6 +791,12 @@ public PrettierConfig config(final Map<String, Object> prettierConfig) {
return this;
}

public PrettierConfig editorconfig(Boolean editorconfig) {
this.editorconfig = editorconfig;
replaceStep();
return this;
}

@Override
protected FormatterStep createStep() {
final Project project = getProject();
Expand All @@ -797,7 +806,7 @@ protected FormatterStep createStep() {
Arrays.asList(project.getProjectDir(), project.getRootDir())),
new com.diffplug.spotless.npm.PrettierConfig(
this.prettierConfigFile != null ? project.file(this.prettierConfigFile) : null,
this.prettierConfig));
this.prettierConfig, this.editorconfig));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,35 @@ void useFileConfig(String prettierVersion) throws IOException {
}
}

@ParameterizedTest(name = "{index}: useEditorconfig with prettier {0}")
@ValueSource(strings = {PRETTIER_VERSION_2, PRETTIER_VERSION_3})
void useEditorconfig(String prettierVersion) throws IOException {
setFile(".prettierrc.yml").toResource("npm/prettier/config/.prettierrc_noop.yml");
setFile(".editorconfig").toResource("npm/prettier/config/.editorconfig_20");
setFile("build.gradle").toLines(
"plugins {",
" id 'com.diffplug.spotless'",
"}",
"repositories { mavenCentral() }",
"spotless {",
" format 'mytypescript', {",
" target 'test.ts'",
" prettier('" + prettierVersion + "').configFile('.prettierrc.yml').editorconfig(true)",
" }",
"}");
setFile("test.ts").toResource("npm/prettier/config/typescript.dirty");
final BuildResult spotlessApply = gradleRunner().withArguments("--stacktrace", "spotlessApply").build();
Assertions.assertThat(spotlessApply.getOutput()).contains("BUILD SUCCESSFUL");
switch (prettierVersion) {
case PRETTIER_VERSION_2:
assertFile("test.ts").sameAsResource("npm/prettier/config/typescript.configfile_prettier_2.clean");
break;
case PRETTIER_VERSION_3:
assertFile("test.ts").sameAsResource("npm/prettier/config/typescript.configfile_prettier_3.clean");
break;
}
}

@ParameterizedTest(name = "{index}: chooseParserBasedOnFilename with prettier {0}")
@ValueSource(strings = {PRETTIER_VERSION_2, PRETTIER_VERSION_3})
void chooseParserBasedOnFilename(String prettierVersion) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ public class Prettier extends AbstractNpmFormatterStepFactory {
@Parameter
private String configFile;

@Parameter
private Boolean editorconfig;

@Override
public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) {

Expand Down Expand Up @@ -101,7 +104,7 @@ public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) {
File baseDir = baseDir(stepConfig);
File buildDir = buildDir(stepConfig);
File cacheDir = cacheDir(stepConfig);
PrettierConfig prettierConfig = new PrettierConfig(configFileHandler, configInline);
PrettierConfig prettierConfig = new PrettierConfig(configFileHandler, configInline, editorconfig);
NpmPathResolver npmPathResolver = npmPathResolver(stepConfig);
return PrettierFormatterStep.create(devDependencies, stepConfig.getProvisioner(), baseDir, buildDir, cacheDir, npmPathResolver, prettierConfig);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,25 @@ void multiple_prettier_configs() throws Exception {

}

@Test
void prettier_editorconfig() throws Exception {
String suffix = "ts";
writePomWithPrettierSteps("**/*." + suffix,
"<prettier>",
" <prettierVersion>1.16.4</prettierVersion>",
" <configFile>.prettierrc.yml</configFile>",
" <editorconfig>true</editorconfig>",
"</prettier>");

String kind = "typescript";
setFile(".prettierrc.yml").toResource("npm/prettier/config/.prettierrc_noop.yml");
setFile(".editorconfig").toResource("npm/prettier/config/.editorconfig_300");
String path = "src/main/" + kind + "/test." + suffix;
setFile(path).toResource("npm/prettier/filetypes/" + kind + "/" + kind + ".dirty");
mavenRunner().withArguments("spotless:apply").runNoError();
assertFile(path).sameAsResource("npm/prettier/filetypes/" + kind + "/" + kind + ".clean");
}

@Test
void custom_plugin() throws Exception {
writePomWithFormatSteps(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[*]
max_line_length = 20
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[*]
max_line_length = 300
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
parser: typescript
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ private void runTestUsingPrettier(String fileType, Map<String, String> dependenc
buildDir(),
null,
npmPathResolver(),
new PrettierConfig(prettierRc, null));
new PrettierConfig(prettierRc, null, null));

try (StepHarness stepHarness = StepHarness.forStep(formatterStep)) {
stepHarness.testResource(dirtyFile, cleanFile);
Expand All @@ -96,7 +96,7 @@ void parserInferenceBasedOnExplicitFilepathIsWorking(String prettierVersion) thr
buildDir(),
null,
npmPathResolver(),
new PrettierConfig(null, ImmutableMap.of("filepath", "anyname.json"))); // should select parser based on this name
new PrettierConfig(null, ImmutableMap.of("filepath", "anyname.json"), null)); // should select parser based on this name

try (StepHarness stepHarness = StepHarness.forStep(formatterStep)) {
stepHarness.testResource(dirtyFile, cleanFile);
Expand All @@ -118,7 +118,7 @@ void parserInferenceBasedOnFilenameIsWorking(String prettierVersion) throws Exce
buildDir(),
null,
npmPathResolver(),
new PrettierConfig(null, Collections.emptyMap()));
new PrettierConfig(null, Collections.emptyMap(), null));

try (StepHarnessWithFile stepHarness = StepHarnessWithFile.forStep(this, formatterStep)) {
stepHarness.testResource("test.json", dirtyFile, cleanFile);
Expand All @@ -134,7 +134,7 @@ void verifyPrettierErrorMessageIsRelayed() throws Exception {
buildDir(),
null,
npmPathResolver(),
new PrettierConfig(null, ImmutableMap.of("parser", "postcss")));
new PrettierConfig(null, ImmutableMap.of("parser", "postcss"), null));
try (StepHarnessWithFile stepHarness = StepHarnessWithFile.forStep(this, formatterStep)) {
stepHarness.expectLintsOfResource("npm/prettier/filetypes/scss/scss.dirty")
.toBe("LINE_UNDEFINED prettier-format(com.diffplug.spotless.npm.SimpleRestClient$SimpleRestResponseException) Unexpected response status code at /prettier/format [HTTP 500] -- (Error while formatting: Error: Couldn't resolve parser \"postcss\") (...)");
Expand Down Expand Up @@ -170,19 +170,27 @@ void runFormatTest(String prettierVersion, PrettierConfig config, String cleanFi
@ParameterizedTest(name = "{index}: defaults are applied with prettier {0}")
@ValueSource(strings = {PRETTIER_VERSION_2, PRETTIER_VERSION_3})
void defaultsAreApplied(String prettierVersion) throws Exception {
runFormatTest(prettierVersion, new PrettierConfig(null, ImmutableMap.of("parser", "typescript")), "defaults_prettier_" + major(prettierVersion));
runFormatTest(prettierVersion, new PrettierConfig(null, ImmutableMap.of("parser", "typescript"), null), "defaults_prettier_" + major(prettierVersion));
}

@ParameterizedTest(name = "{index}: config file options are applied with prettier {0}")
@ValueSource(strings = {PRETTIER_VERSION_2, PRETTIER_VERSION_3})
void configFileOptionsAreApplied(String prettierVersion) throws Exception {
runFormatTest(prettierVersion, new PrettierConfig(createTestFile(FILEDIR + ".prettierrc.yml"), null), "configfile_prettier_" + major(prettierVersion));
runFormatTest(prettierVersion, new PrettierConfig(createTestFile(FILEDIR + ".prettierrc.yml"), null, null), "configfile_prettier_" + major(prettierVersion));
}

@ParameterizedTest(name = "{index}: config file options can be overriden with prettier {0}")
@ParameterizedTest(name = "{index}: config file options can be overridden with prettier {0}")
@ValueSource(strings = {PRETTIER_VERSION_2, PRETTIER_VERSION_3})
void configFileOptionsCanBeOverriden(String prettierVersion) throws Exception {
runFormatTest(prettierVersion, new PrettierConfig(createTestFile(FILEDIR + ".prettierrc.yml"), ImmutableMap.of("printWidth", 300)), "override_prettier_" + major(prettierVersion));
void configFileOptionsCanBeOverridden(String prettierVersion) throws Exception {
runFormatTest(prettierVersion, new PrettierConfig(createTestFile(FILEDIR + ".prettierrc.yml"), ImmutableMap.of("printWidth", 300), null), "override_prettier_" + major(prettierVersion));
}

@ParameterizedTest(name = "{index}: config file options can be extended with editorconfig with prettier {0}")
@ValueSource(strings = {PRETTIER_VERSION_2, PRETTIER_VERSION_3})
void configFileOptionsCanBeExtendedWithEditorconfig(String prettierVersion) throws Exception {
setFile(".editorconfig").toResource(FILEDIR + ".editorconfig_300");
File prettierConfigFile = setFile(".prettierrc.yml").toResource(FILEDIR + ".prettierrc_noop.yml");
runFormatTest(prettierVersion, new PrettierConfig(prettierConfigFile, null, true), "override_prettier_" + major(prettierVersion));
}

private String major(String semVer) {
Expand All @@ -194,7 +202,7 @@ private String major(String semVer) {
void equality() {
new SerializableEqualityTester() {
String prettierVersion = "3.0.0";
PrettierConfig config = new PrettierConfig(null, Map.of("parser", "typescript"));
PrettierConfig config = new PrettierConfig(null, Map.of("parser", "typescript"), null);

@Override
protected void setupTest(API api) {
Expand All @@ -203,7 +211,7 @@ protected void setupTest(API api) {
// change the groupArtifact, and it's different
prettierVersion = "2.8.8";
api.areDifferentThan();
config = new PrettierConfig(null, Map.of("parser", "css"));
config = new PrettierConfig(null, Map.of("parser", "css"), null);
api.areDifferentThan();
}

Expand Down
Loading