diff --git a/CHANGES.md b/CHANGES.md
index e01d6abb37..36caa98ab8 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -13,6 +13,9 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
### Changed
* Support configuring the Equo P2 cache. ([#2238](https://github.com/diffplug/spotless/pull/2238))
+* Add explicit support for JSONC / CSS via biome, via the file extensions `.css` and `.jsonc`.
+ ([#2259](https://github.com/diffplug/spotless/pull/2259))
+
## [3.0.0.BETA2] - 2024-08-25
### Changed
* Support toning down sortPom logging. ([#2185](https://github.com/diffplug/spotless/pull/2185))
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 27e6221e76..5ce03c49ce 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -164,13 +164,13 @@ concerning what you are working on:
```shell
# Run only from test from the "lib" project
-gradlew :testlib:test --tests com.diffplug.spotless.generic.IndentStepTest
+./gradlew :testlib:test --tests com.diffplug.spotless.generic.IndentStepTest
# Run only one test from the "plugin-maven" project
-gradlew :plugin-maven:test --tests com.diffplug.spotless.maven.pom.SortPomMavenTest
+./gradlew :plugin-maven:test --tests com.diffplug.spotless.maven.pom.SortPomMavenTest
# Run only one test from the "plugin-gradle" project
-gradlew :plugin-gradle:test --tests com.diffplug.gradle.spotless.FreshMarkExtensionTest
+./gradlew :plugin-gradle:test --tests com.diffplug.gradle.spotless.FreshMarkExtensionTest
```
## Check and format code
diff --git a/lib/src/main/java/com/diffplug/spotless/biome/BiomeStep.java b/lib/src/main/java/com/diffplug/spotless/biome/BiomeStep.java
index 2db9e8cb2a..09a42ae4a0 100644
--- a/lib/src/main/java/com/diffplug/spotless/biome/BiomeStep.java
+++ b/lib/src/main/java/com/diffplug/spotless/biome/BiomeStep.java
@@ -55,7 +55,7 @@ public class BiomeStep {
/**
* The language (syntax) of the input files to format. When null
or
* the empty string, the language is detected automatically from the file name.
- * Currently the following languages are supported by Biome:
+ * Currently, the following languages are supported by Biome:
*
* - js (JavaScript)
* - jsx (JavaScript + JSX)
@@ -65,7 +65,9 @@ public class BiomeStep {
* - tsx (TypeScript + JSX)
* - ts? (TypeScript or TypeScript + JSX, depending on the file
* extension)
+ * - css (CSS, requires biome >= 1.9.0)
* - json (JSON)
+ * - jsonc (JSON + comments)
*
*/
private String language;
@@ -274,7 +276,9 @@ public BiomeStep withConfigPath(String configPath) {
* tsx (TypeScript + JSX)
* ts? (TypeScript or TypeScript + JSX, depending on the file
* extension)
+ * css (CSS, requires biome >= 1.9.0)
* json (JSON)
+ * jsonc (JSON + comments)
*
*
* @param language The language of the files to format.
@@ -450,7 +454,7 @@ private String format(ProcessRunner runner, String input, File file) throws IOEx
* expected language / syntax. Biome always determined the language from the file
* extension. This method returns the file name for the desired language when a
* language was requested explicitly, or the file name of the input file for
- * auto detection.
+ * auto-detection.
*
* @param file File to be formatted.
* @return The file name to pass to the Biome executable.
@@ -479,6 +483,10 @@ private String resolveFileName(File file) {
return "tsx".equals(ext) ? name : "file.tsx";
case "json":
return "json".equals(ext) ? name : "file.json";
+ case "jsonc":
+ return "jsonc".equals(ext) ? name : "file.jsonc";
+ case "css":
+ return "css".equals(ext) ? name : "file.css";
// so that we can support new languages such as css or yaml when Biome adds
// support for them without having to change the code
default:
diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md
index f33abfc3f4..18c1ee997a 100644
--- a/plugin-gradle/CHANGES.md
+++ b/plugin-gradle/CHANGES.md
@@ -4,6 +4,10 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
## [Unreleased]
+* Add explicit support for CSS via biome. Formatting CSS via biome was already supported as a general
+ formatting step. Biome supports formatting CSS as of 1.8.0 (experimental, opt-in) and 1.9.0 (stable).
+ ([#2259](https://github.com/diffplug/spotless/pull/2259))
+
## [7.0.0.BETA2] - 2024-08-25
### Changed
* Support toning down sortPom logging. ([#2185](https://github.com/diffplug/spotless/pull/2185))
diff --git a/plugin-gradle/README.md b/plugin-gradle/README.md
index 9f430b4e48..370ff36141 100644
--- a/plugin-gradle/README.md
+++ b/plugin-gradle/README.md
@@ -1111,6 +1111,22 @@ spotless {
}
```
+## CSS
+
+`com.diffplug.gradle.spotless.CssExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/7.0.0.BETA2/com/diffplug/gradle/spotless/CssExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/CssExtension.java)
+
+```gradle
+spotless {
+ css {
+ target 'css/**/*.css' // default: '**/*.css'
+
+ biome('1.8.3') // has its own section below
+ }
+}
+```
+
+Note regarding biome: Biome supports formatting CSS as of 1.8.0 (experimental, opt-in) and 1.9.0 (stable).
+
## Prettier
[homepage](https://prettier.io/). [changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md). [official plugins](https://prettier.io/docs/en/plugins.html#official-plugins). [community plugins](https://prettier.io/docs/en/plugins.html#community-plugins). Prettier is a formatter that can format almost every anything - JavaScript, JSX, Angular, Vue, Flow, TypeScript, CSS, Less, SCSS, HTML, JSON, GraphQL, Markdown (including GFM and MDX), and YAML. It can format even more [using plugins](https://prettier.io/docs/en/plugins.html) (PHP, Ruby, Swift, XML, Apex, Elm, Java (!!), Kotlin, pgSQL, .properties, solidity, svelte, toml, shellscript, ...).
@@ -1311,6 +1327,8 @@ is pretty fast. It can currently format JavaScript, TypeScript, JSX, and JSON, a
You can use Biome in any language-specific format for supported languages, but
usually you will be creating a generic format.
+Note regarding biome: Biome supports formatting CSS as of 1.8.0 (experimental, opt-in) and 1.9.0 (stable).
+
```gradle
spotless {
format 'styling', {
diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/BiomeStepConfig.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/BiomeStepConfig.java
index d66048a7b0..e26ece6a18 100644
--- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/BiomeStepConfig.java
+++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/BiomeStepConfig.java
@@ -170,7 +170,7 @@ protected FormatterStep createStep() {
/**
* Gets the language (syntax) of the input files to format. When
* null
or the empty string, the language is detected automatically
- * from the file name. Currently the following languages are supported by Biome:
+ * from the file name. Currently, the following languages are supported by Biome:
*
* - js (JavaScript)
* - jsx (JavaScript + JSX)
@@ -180,7 +180,9 @@ protected FormatterStep createStep() {
* - tsx (TypeScript + JSX)
* - ts? (TypeScript or TypeScript + JSX, depending on the file
* extension)
+ * - css (CSS, requires biome >= 1.9.0)
* - json (JSON)
+ * - jsonc (JSON + comments)
*
*
* @return The language of the input files.
diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/CssExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/CssExtension.java
new file mode 100644
index 0000000000..f3dd15ccb3
--- /dev/null
+++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/CssExtension.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2024 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.gradle.spotless;
+
+import javax.inject.Inject;
+
+import com.diffplug.spotless.biome.BiomeFlavor;
+
+/** Gradle step for formatting CSS files. */
+public class CssExtension extends FormatExtension {
+ private static final String CSS_FILE_EXTENSION = "**/*.css";
+
+ static final String NAME = "css";
+
+ @Inject
+ public CssExtension(SpotlessExtension spotless) {
+ super(spotless);
+ }
+
+ /** If the user hasn't specified files, assume all CSS files should be checked. */
+ @Override
+ protected void setupTask(SpotlessTask task) {
+ if (target == null) {
+ target = parseTarget(CSS_FILE_EXTENSION);
+ }
+ super.setupTask(task);
+ }
+
+ /**
+ * Adds the default version of the biome formatter.
+ * Defaults to downloading the default Biome version from the network. To work
+ * offline, you can specify the path to the Biome executable via
+ * {@code biome().pathToExe(...)}.
+ */
+ public BiomeCss biome() {
+ return biome(null);
+ }
+
+ /**
+ * Adds the given version of the biome formatter.
+ * Defaults to downloading the default Biome version from the network. To work
+ * offline, you can specify the path to the Biome executable via
+ * {@code biome().pathToExe(...)}.
+ * @param version Biome version to use.
+ */
+ public BiomeCss biome(String version) {
+ var biomeConfig = new BiomeCss(version);
+ addStep(biomeConfig.createStep());
+ return biomeConfig;
+ }
+
+ /**
+ * Biome formatter step for CSS.
+ */
+ public class BiomeCss extends BiomeStepConfig {
+ /**
+ * Creates a new Biome formatter step config for formatting CSS files. Unless
+ * overwritten, the given Biome version is downloaded from the network.
+ *
+ * @param version Biome version to use.
+ */
+ public BiomeCss(String version) {
+ super(getProject(), CssExtension.this::replaceStep, BiomeFlavor.BIOME, version);
+ }
+
+ @Override
+ protected String getLanguage() {
+ return "css";
+ }
+
+ @Override
+ protected BiomeCss getThis() {
+ return this;
+ }
+ }
+}
diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java
index 27b81ccef5..ac1b3c42a5 100644
--- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java
+++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java
@@ -780,7 +780,9 @@ public BiomeGeneric(String version) {
* tsx (TypeScript + JSX)
* ts? (TypeScript or TypeScript + JSX, depending on the file
* extension)
+ * css (CSS, requires biome >= 1.9.0)
* json (JSON)
+ * jsonc (JSON + comments)
*
*
* @param language The language of the files to format.
diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java
index 276bdadcfd..e883953eaa 100644
--- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java
+++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java
@@ -231,6 +231,12 @@ public void go(Action closure) {
format(GoExtension.NAME, GoExtension.class, closure);
}
+ /** Configures the special CSS-specific extension. */
+ public void css(Action closure) {
+ requireNonNull(closure);
+ format(CssExtension.NAME, CssExtension.class, closure);
+ }
+
/** Configures the special POM-specific extension. */
public void pom(Action closure) {
requireNonNull(closure);
diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/BiomeIntegrationTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/BiomeIntegrationTest.java
index ba39af1705..1456f9d793 100644
--- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/BiomeIntegrationTest.java
+++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/BiomeIntegrationTest.java
@@ -19,19 +19,73 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import java.io.IOException;
-
import org.junit.jupiter.api.Test;
import org.owasp.encoder.Encode;
+/**
+ * Tests for the Biome formatter used via the Gradle spotless plugin.
+ */
class BiomeIntegrationTest extends GradleIntegrationHarness {
+ /**
+ * Tests that biome can be used as a JSON formatting step, using biome 1.8.3 which
+ * requires opt-in.
+ *
+ * @throws Exception When a test failure occurs.
+ */
+ @Test
+ void asCssStepExperimental() throws Exception {
+ setFile("build.gradle").toLines(
+ "plugins {",
+ " id 'com.diffplug.spotless'",
+ "}",
+ "repositories { mavenCentral() }",
+ "spotless {",
+ " css {",
+ " target '**/*.css'",
+ " biome('1.8.3').configPath('configs')",
+ " }",
+ "}");
+ setFile("biome_test.css").toResource("biome/css/fileBefore.css");
+ setFile("configs/biome.json").toResource("biome/config/css-enabled.json");
+
+ var spotlessApply = gradleRunner().withArguments("--stacktrace", "spotlessApply").build();
+ assertThat(spotlessApply.getOutput()).contains("BUILD SUCCESSFUL");
+ assertFile("biome_test.css").sameAsResource("biome/css/fileAfter.css");
+ }
+
+ /**
+ * Tests that biome can be used as a JSON formatting step, using biome 1.9.0 which
+ * does not require opt-in.
+ *
+ * @throws Exception When a test failure occurs.
+ */
+ @Test
+ void asCssStepStable() throws Exception {
+ setFile("build.gradle").toLines(
+ "plugins {",
+ " id 'com.diffplug.spotless'",
+ "}",
+ "repositories { mavenCentral() }",
+ "spotless {",
+ " css {",
+ " target '**/*.css'",
+ " biome('1.9.0')",
+ " }",
+ "}");
+ setFile("biome_test.css").toResource("biome/css/fileBefore.css");
+
+ var spotlessApply = gradleRunner().withArguments("--stacktrace", "spotlessApply").build();
+ assertThat(spotlessApply.getOutput()).contains("BUILD SUCCESSFUL");
+ assertFile("biome_test.css").sameAsResource("biome/css/fileAfter.css");
+ }
+
/**
* Tests that biome can be used as a generic formatting step.
*
* @throws Exception When a test failure occurs.
*/
@Test
- void asGenericStep() throws IOException {
+ void asGenericStep() throws Exception {
setFile("build.gradle").toLines(
"plugins {",
" id 'com.diffplug.spotless'",
diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md
index 9e43685b36..46100648a7 100644
--- a/plugin-maven/CHANGES.md
+++ b/plugin-maven/CHANGES.md
@@ -6,6 +6,10 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
### Changed
* Leverage local repository for Equo P2 cache. ([#2238](https://github.com/diffplug/spotless/pull/2238))
+* Add explicit support for CSS via biome. Formatting CSS via biome was already supported as a general
+ formatting step. Biome supports formatting CSS as of 1.8.0 (experimental, opt-in) and 1.9.0 (stable).
+ ([#2259](https://github.com/diffplug/spotless/pull/2259))
+
## [2.44.0.BETA2] - 2024-08-25
### Changed
* Support toning down sortPom logging. ([#2185](https://github.com/diffplug/spotless/pull/2185))
diff --git a/plugin-maven/README.md b/plugin-maven/README.md
index 48eeea7efc..130d9c20df 100644
--- a/plugin-maven/README.md
+++ b/plugin-maven/README.md
@@ -1118,6 +1118,30 @@ Standard Go formatter, part of Go distribution.
```
+## CSS
+
+[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/css/Css.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/css).
+
+```xml
+
+
+
+
+ src/main/css/**/*.css
+ src/test/css/**/*.css
+
+
+
+
+
+ /* (C)$YEAR */
+
+
+
+```
+
+Note regarding biome: Biome supports formatting CSS as of 1.8.0 (experimental, opt-in) and 1.9.0 (stable).
+
## Prettier
[homepage](https://prettier.io/). [changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md). [official plugins](https://prettier.io/docs/en/plugins.html#official-plugins). [community plugins](https://prettier.io/docs/en/plugins.html#community-plugins). Prettier is a formatter that can format almost every anything - JavaScript, JSX, Angular, Vue, Flow, TypeScript, CSS, Less, SCSS, HTML, JSON, GraphQL, Markdown (including GFM and MDX), and YAML. It can format even more [using plugins](https://prettier.io/docs/en/plugins.html) (PHP, Ruby, Swift, XML, Apex, Elm, Java (!!), Kotlin, pgSQL, .properties, solidity, svelte, toml, shellscript, ...).
@@ -1340,6 +1364,8 @@ is pretty fast. It can currently format JavaScript, TypeScript, JSX, and JSON, a
You can use Biome in any language-specific format for supported languages, but
usually you will be creating a generic format.
+Note regarding CSS: Biome supports formatting CSS as of 1.8.0 (experimental, opt-in) and 1.9.0 (stable).
+
```xml
@@ -1355,7 +1381,7 @@ usually you will be creating a generic format.
${project.basedir}/path/to/config/dir
-
+
ts
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 004c680e02..8ade0cac53 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
@@ -59,6 +59,7 @@
import com.diffplug.spotless.generic.LicenseHeaderStep;
import com.diffplug.spotless.maven.antlr4.Antlr4;
import com.diffplug.spotless.maven.cpp.Cpp;
+import com.diffplug.spotless.maven.css.Css;
import com.diffplug.spotless.maven.generic.Format;
import com.diffplug.spotless.maven.generic.LicenseHeader;
import com.diffplug.spotless.maven.gherkin.Gherkin;
@@ -141,6 +142,9 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo {
@Parameter
private List formats = Collections.emptyList();
+ @Parameter
+ private Css css;
+
@Parameter
private Groovy groovy;
@@ -377,7 +381,7 @@ private FileLocator getFileLocator() {
}
private List getFormatterFactories() {
- return Stream.concat(formats.stream(), Stream.of(groovy, java, scala, kotlin, cpp, typescript, javascript, antlr4, pom, sql, python, markdown, json, shell, yaml, gherkin, go))
+ return Stream.concat(formats.stream(), Stream.of(groovy, java, scala, kotlin, cpp, css, typescript, javascript, antlr4, pom, sql, python, markdown, json, shell, yaml, gherkin, go))
.filter(Objects::nonNull)
.map(factory -> factory.init(repositorySystemSession))
.collect(toList());
diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/css/BiomeCss.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/css/BiomeCss.java
new file mode 100644
index 0000000000..ca96f47cfe
--- /dev/null
+++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/css/BiomeCss.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2016-2024 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.css;
+
+import com.diffplug.spotless.biome.BiomeFlavor;
+import com.diffplug.spotless.maven.generic.AbstractBiome;
+
+/**
+ * Biome formatter step for CSS.
+ */
+public class BiomeCss extends AbstractBiome {
+ public BiomeCss() {
+ super(BiomeFlavor.BIOME);
+ }
+
+ @Override
+ protected String getLanguage() {
+ return "css";
+ }
+}
diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/css/Css.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/css/Css.java
new file mode 100644
index 0000000000..4d465d8939
--- /dev/null
+++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/css/Css.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023-2024 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.css;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.apache.maven.project.MavenProject;
+
+import com.diffplug.spotless.maven.FormatterFactory;
+
+/**
+ * A {@link FormatterFactory} implementation that corresponds to {@code ...} configuration element.
+ */
+public class Css extends FormatterFactory {
+ @Override
+ public Set defaultIncludes(MavenProject project) {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public String licenseHeaderDelimiter() {
+ return null;
+ }
+
+ public void addBiome(BiomeCss biome) {
+ addStepFactory(biome);
+ }
+}
diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/AbstractBiome.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/AbstractBiome.java
index 7bc502edf1..f1473adf45 100644
--- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/AbstractBiome.java
+++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/AbstractBiome.java
@@ -117,7 +117,9 @@ public FormatterStep newFormatterStep(FormatterStepConfig config) {
* tsx (TypeScript + JSX)
* ts? (TypeScript or TypeScript + JSX, depending on the file
* extension)
+ * css (CSS, requires biome >= 1.9.0)
* json (JSON)
+ * jsonc (JSON + comments)
*
*
* @return The language of the input files.
diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/Biome.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/Biome.java
index 133e21c302..99cede1065 100644
--- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/Biome.java
+++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/Biome.java
@@ -32,8 +32,7 @@ public Biome() {
/**
* Gets the language (syntax) of the input files to format. When
* null
or the empty string, the language is detected automatically
- * from the file name. Currently the following languages are supported by Biome:
- *
+ * from the file name. Currently, the following languages are supported by Biome:
*
* - js (JavaScript)
* - jsx (JavaScript + JSX)
@@ -43,8 +42,9 @@ public Biome() {
* - tsx (TypeScript + JSX)
* - ts? (TypeScript or TypeScript + JSX, depending on the file
* extension)
+ * - css (CSS, requires biome >= 1.9.0)
* - json (JSON)
- *
+ * - jsonc (JSON + comments)
*
*
* @return The language of the input files.
diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationHarness.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationHarness.java
index 9e2e70c60f..9dbdf52339 100644
--- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationHarness.java
+++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationHarness.java
@@ -179,6 +179,10 @@ protected void writePomWithJsonSteps(String... steps) throws IOException {
writePom(groupWithSteps("json", including("**/*.json"), steps));
}
+ protected void writePomWithCssSteps(String... steps) throws IOException {
+ writePom(groupWithSteps("css", including("**/*.css"), steps));
+ }
+
protected void writePomWithShellSteps(String... steps) throws IOException {
writePom(groupWithSteps("shell", including("**/*.sh"), steps));
}
diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/biome/BiomeMavenTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/biome/BiomeMavenTest.java
index ff763c3cf8..5bb7424ef9 100644
--- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/biome/BiomeMavenTest.java
+++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/biome/BiomeMavenTest.java
@@ -24,7 +24,40 @@
import com.diffplug.spotless.maven.MavenIntegrationHarness;
+/**
+ * Tests for the Biome formatter used via the Maven spotless plugin.
+ */
class BiomeMavenTest extends MavenIntegrationHarness {
+ /**
+ * Tests that biome can be used as a CSS formatting step, using biome 1.8.3
+ * which requires opt-in.
+ *
+ * @throws Exception When a test failure occurs.
+ */
+ @Test
+ void asCssStepExperimental() throws Exception {
+ writePomWithCssSteps("**/*.css", "1.8.3configs");
+ setFile("biome_test.css").toResource("biome/css/fileBefore.css");
+ setFile("configs/biome.json").toResource("biome/config/css-enabled.json");
+ mavenRunner().withArguments("spotless:apply").runNoError();
+ assertFile("biome_test.css").sameAsResource("biome/css/fileAfter.css");
+ }
+
+ /**
+ * Tests that biome can be used as a CSS formatting step, with biome 1.9.0
+ * which does not require opt-in.
+ *
+ * @throws Exception When a test failure occurs.
+ */
+ @Test
+ void asCssStepStable() throws Exception {
+ writePomWithCssSteps("**/*.js", "1.9.0");
+ setFile("biome_test.css").toResource("biome/css/fileBefore.css");
+ var res = mavenRunner().withArguments("spotless:apply").runNoError();
+ System.out.println(res.stdOutUtf8());
+ assertFile("biome_test.css").sameAsResource("biome/css/fileAfter.css");
+ }
+
/**
* Tests that Biome can be used as a generic formatting step.
*
diff --git a/testlib/src/main/resources/biome/config/css-enabled.json b/testlib/src/main/resources/biome/config/css-enabled.json
new file mode 100644
index 0000000000..692de05fe6
--- /dev/null
+++ b/testlib/src/main/resources/biome/config/css-enabled.json
@@ -0,0 +1,19 @@
+{
+ "css": {
+ "linter": {
+ "enabled": true
+ },
+ "formatter": {
+ "enabled": true
+ }
+ },
+ "formatter": {
+ "enabled": true,
+ "indentStyle": "tab",
+ "lineWidth": 80,
+ "formatWithErrors": false
+ },
+ "linter": {
+ "enabled": false
+ }
+ }
\ No newline at end of file
diff --git a/testlib/src/main/resources/biome/css/fileAfter.css b/testlib/src/main/resources/biome/css/fileAfter.css
new file mode 100644
index 0000000000..0fc2cd37a2
--- /dev/null
+++ b/testlib/src/main/resources/biome/css/fileAfter.css
@@ -0,0 +1,7 @@
+.foobar {
+ color: red;
+ font-weight: bold;
+ &.foobar--large {
+ font-size: 20px;
+ }
+}
diff --git a/testlib/src/main/resources/biome/css/fileBefore.css b/testlib/src/main/resources/biome/css/fileBefore.css
new file mode 100644
index 0000000000..cfa88da947
--- /dev/null
+++ b/testlib/src/main/resources/biome/css/fileBefore.css
@@ -0,0 +1,12 @@
+ .foobar { color:red;font-weight: bold;
+&.foobar--large {
+
+
+
+ font-size: 20px;
+
+
+ }
+
+
+ }
\ No newline at end of file
diff --git a/testlib/src/main/resources/biome/jsonc/fileAfter.jsonc b/testlib/src/main/resources/biome/jsonc/fileAfter.jsonc
new file mode 100644
index 0000000000..439d19ba1f
--- /dev/null
+++ b/testlib/src/main/resources/biome/jsonc/fileAfter.jsonc
@@ -0,0 +1,6 @@
+{
+ // some comment
+ "a": [1, 2, 3],
+ "b": 9,
+ "c": null
+}
diff --git a/testlib/src/main/resources/biome/jsonc/fileBefore.jsonc b/testlib/src/main/resources/biome/jsonc/fileBefore.jsonc
new file mode 100644
index 0000000000..d7a2ca689f
--- /dev/null
+++ b/testlib/src/main/resources/biome/jsonc/fileBefore.jsonc
@@ -0,0 +1,8 @@
+ {
+ // some comment
+ "a":[1,2,3
+
+],
+ "b":9,
+ "c" : null
+ }
\ No newline at end of file
diff --git a/testlib/src/test/java/com/diffplug/spotless/biome/BiomeStepTest.java b/testlib/src/test/java/com/diffplug/spotless/biome/BiomeStepTest.java
index 0ad2f68783..87c4d6e91f 100644
--- a/testlib/src/test/java/com/diffplug/spotless/biome/BiomeStepTest.java
+++ b/testlib/src/test/java/com/diffplug/spotless/biome/BiomeStepTest.java
@@ -28,6 +28,9 @@
import com.diffplug.spotless.StepHarnessWithFile;
import com.diffplug.spotless.ThrowingEx;
+/**
+ * Tests for formatting files via the {@link BiomeStep}.
+ */
class BiomeStepTest extends ResourceHarness {
private static String downloadDir;
@@ -38,263 +41,329 @@ static void createDownloadDir() throws IOException {
downloadDir = userHome.resolve(".gradle").resolve("rome-dl-test").toAbsolutePath().normalize().toString();
}
+ /**
+ * Tests that files can be formatted without setting the input language
+ * explicitly.
+ */
@Nested
- class Biome {
+ class AutoDetectLanguage {
+ /**
+ * Tests that a *.cjs file can be formatted without setting the input language
+ * explicitly.
+ */
+ @Test
+ void testAutoDetectCjs() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/js/fileBefore.cjs", "biome/js/fileAfter.cjs");
+ }
+
+ /**
+ * Tests that a *.cts file can be formatted without setting the input language
+ * explicitly.
+ */
+ @Test
+ void testAutoDetectCts() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/ts/fileBefore.cts", "biome/ts/fileAfter.cts");
+ }
+
+ /**
+ * Tests that a *.css file can be formatted without setting the input language
+ * explicitly, using biome 1.8.3 which does require opt-in.
+ */
+ @Test
+ void testAutoDetectCssExperimental() {
+ var path = createBiomeConfig("biome/config/css-enabled.json");
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.8.3", downloadDir.toString()).withConfigPath(path).create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/css/fileBefore.css", "biome/css/fileAfter.css");
+ }
+
+ /**
+ * Tests that a *.css file can be formatted without setting the input language
+ * explicitly, using biome 1.9.0 which does not require opt-in.
+ */
+ @Test
+ void testAutoDetectCssStable() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.9.0", downloadDir.toString()).create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/css/fileBefore.css", "biome/css/fileAfter.css");
+ }
+
+ /**
+ * Tests that a *.js file can be formatted without setting the input language
+ * explicitly.
+ */
+ @Test
+ void testAutoDetectJs() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/js/fileBefore.js", "biome/js/fileAfter.js");
+ }
+
/**
- * Tests that files can be formatted without setting the input language
+ * Tests that a *.js file can be formatted without setting the input language
* explicitly.
*/
- @Nested
- class AutoDetectLanguage {
- /**
- * Tests that a *.cjs file can be formatted without setting the input language
- * explicitly.
- */
- @Test
- void testAutoDetectCjs() {
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/js/fileBefore.cjs", "biome/js/fileAfter.cjs");
- }
-
- /**
- * Tests that a *.cts file can be formatted without setting the input language
- * explicitly.
- */
- @Test
- void testAutoDetectCts() {
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/ts/fileBefore.cts", "biome/ts/fileAfter.cts");
- }
-
- /**
- * Tests that a *.js file can be formatted without setting the input language
- * explicitly.
- */
- @Test
- void testAutoDetectJs() {
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/js/fileBefore.js", "biome/js/fileAfter.js");
- }
-
- /**
- * Tests that a *.js file can be formatted without setting the input language
- * explicitly.
- */
- @Test
- void testAutoDetectJson() {
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/json/fileBefore.json", "biome/json/fileAfter.json");
- }
-
- /**
- * Tests that a *.jsx file can be formatted without setting the input language
- * explicitly.
- */
- @Test
- void testAutoDetectJsx() {
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/js/fileBefore.jsx", "biome/js/fileAfter.jsx");
- }
-
- /**
- * Tests that a *.mjs file can be formatted without setting the input language
- * explicitly.
- */
- @Test
- void testAutoDetectMjs() {
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/js/fileBefore.mjs", "biome/js/fileAfter.mjs");
- }
-
- /**
- * Tests that a *.mts file can be formatted without setting the input language
- * explicitly.
- */
- @Test
- void testAutoDetectMts() {
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/ts/fileBefore.mts", "biome/ts/fileAfter.mts");
- }
-
- /**
- * Tests that a *.ts file can be formatted without setting the input language
- * explicitly.
- */
- @Test
- void testAutoDetectTs() {
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/ts/fileBefore.ts", "biome/ts/fileAfter.ts");
- }
-
- /**
- * Tests that a *.tsx file can be formatted without setting the input language
- * explicitly.
- */
- @Test
- void testAutoDetectTsx() {
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/ts/fileBefore.tsx", "biome/ts/fileAfter.tsx");
- }
-
- /**
- * Biome is hard-coded to ignore certain files, such as package.json. Since version 1.5.0,
- * the biome CLI does not output any formatted code anymore, whereas previously it printed
- * the input as-is. This tests checks that when the biome formatter outputs an empty string,
- * the contents of the file to format are used instead.
- */
- @Test
- void preservesIgnoredFiles() {
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.5.0", downloadDir.toString()).create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/json/package.json", "biome/json/packageAfter.json");
- }
+ @Test
+ void testAutoDetectJson() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/json/fileBefore.json", "biome/json/fileAfter.json");
}
- @Nested
- class ConfigFile {
- /**
- * Test formatting with the line width in the config file set to 120.
- */
- @Test
- void testLineWidth120() {
- var path = createBiomeConfig("biome/config/line-width-120.json");
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withConfigPath(path).create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/js/longLineBefore.js", "biome/js/longLineAfter120.js");
- }
-
- /**
- * Test formatting with the line width in the config file set to 120.
- */
- @Test
- void testLineWidth80() {
- var path = createBiomeConfig("biome/config/line-width-80.json");
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withConfigPath(path).create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/js/longLineBefore.js", "biome/js/longLineAfter80.js");
- }
-
- private String createBiomeConfig(String name) {
- var config = createTestFile(name).toPath();
- var dir = config.getParent();
- var rome = dir.resolve("biome.json");
- ThrowingEx.run(() -> Files.copy(config, rome));
- return dir.toString();
- }
+ /**
+ * Tests that a *.jsonc file can be formatted without setting the input language
+ * explicitly.
+ */
+ @Test
+ void testAutoDetectJsonc() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/jsonc/fileBefore.jsonc", "biome/jsonc/fileAfter.jsonc");
}
/**
- * Tests that files can be formatted when setting the input language explicitly.
+ * Tests that a *.jsx file can be formatted without setting the input language
+ * explicitly.
*/
- @Nested
- class ExplicitLanguage {
- /**
- * Tests that a *.cjs file can be formatted when setting the input language
- * explicitly.
- */
- @Test
- void testAutoDetectCjs() {
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withLanguage("js").create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/js/fileBefore.cjs", "biome/js/fileAfter.cjs");
- }
-
- /**
- * Tests that a *.cts file can be formatted when setting the input language
- * explicitly.
- */
- @Test
- void testAutoDetectCts() {
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withLanguage("ts").create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/ts/fileBefore.cts", "biome/ts/fileAfter.cts");
- }
-
- /**
- * Tests that a *.js file can be formatted when setting the input language
- * explicitly.
- */
- @Test
- void testAutoDetectJs() {
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withLanguage("js").create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/js/fileBefore.js", "biome/js/fileAfter.js");
- }
-
- /**
- * Tests that a *.json file can be formatted when setting the input language
- * explicitly.
- */
- @Test
- void testAutoDetectJson() {
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withLanguage("json").create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/json/fileBefore.json", "biome/json/fileAfter.json");
- }
-
- /**
- * Tests that a *.jsx file can be formatted when setting the input language
- * explicitly.
- */
- @Test
- void testAutoDetectJsx() {
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withLanguage("jsx").create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/js/fileBefore.jsx", "biome/js/fileAfter.jsx");
- }
-
- /**
- * Tests that a *.mjs file can be formatted without setting the input language
- * explicitly.
- */
- @Test
- void testAutoDetectMjs() {
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withLanguage("js").create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/js/fileBefore.mjs", "biome/js/fileAfter.mjs");
- }
-
- /**
- * Tests that a *.mts file can be formatted when setting the input language
- * explicitly.
- */
- @Test
- void testAutoDetectMts() {
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withLanguage("ts").create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/ts/fileBefore.mts", "biome/ts/fileAfter.mts");
- }
-
- /**
- * Tests that a *.ts file can be formatted when setting the input language
- * explicitly.
- */
- @Test
- void testAutoDetectTs() {
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withLanguage("ts").create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/ts/fileBefore.ts", "biome/ts/fileAfter.ts");
- }
-
- /**
- * Tests that a *.tsx file can be formatted when setting the input language
- * explicitly.
- */
- @Test
- void testAutoDetectTsx() {
- var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withLanguage("tsx").create();
- var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
- stepHarness.testResource("biome/ts/fileBefore.tsx", "biome/ts/fileAfter.tsx");
- }
+ @Test
+ void testAutoDetectJsx() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/js/fileBefore.jsx", "biome/js/fileAfter.jsx");
}
+
+ /**
+ * Tests that a *.mjs file can be formatted without setting the input language
+ * explicitly.
+ */
+ @Test
+ void testAutoDetectMjs() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/js/fileBefore.mjs", "biome/js/fileAfter.mjs");
+ }
+
+ /**
+ * Tests that a *.mts file can be formatted without setting the input language
+ * explicitly.
+ */
+ @Test
+ void testAutoDetectMts() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/ts/fileBefore.mts", "biome/ts/fileAfter.mts");
+ }
+
+ /**
+ * Tests that a *.ts file can be formatted without setting the input language
+ * explicitly.
+ */
+ @Test
+ void testAutoDetectTs() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/ts/fileBefore.ts", "biome/ts/fileAfter.ts");
+ }
+
+ /**
+ * Tests that a *.tsx file can be formatted without setting the input language
+ * explicitly.
+ */
+ @Test
+ void testAutoDetectTsx() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/ts/fileBefore.tsx", "biome/ts/fileAfter.tsx");
+ }
+
+ /**
+ * Biome is hard-coded to ignore certain files, such as package.json. Since version 1.5.0,
+ * the biome CLI does not output any formatted code anymore, whereas previously it printed
+ * the input as-is. This tests checks that when the biome formatter outputs an empty string,
+ * the contents of the file to format are used instead.
+ */
+ @Test
+ void preservesIgnoredFiles() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.5.0", downloadDir.toString()).create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/json/package.json", "biome/json/packageAfter.json");
+ }
+ }
+
+ @Nested
+ class ConfigFile {
+ /**
+ * Test formatting with the line width in the config file set to 120.
+ */
+ @Test
+ void testLineWidth120() {
+ var path = createBiomeConfig("biome/config/line-width-120.json");
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withConfigPath(path).create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/js/longLineBefore.js", "biome/js/longLineAfter120.js");
+ }
+
+ /**
+ * Test formatting with the line width in the config file set to 120.
+ */
+ @Test
+ void testLineWidth80() {
+ var path = createBiomeConfig("biome/config/line-width-80.json");
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withConfigPath(path).create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/js/longLineBefore.js", "biome/js/longLineAfter80.js");
+ }
+
+ }
+
+ /**
+ * Tests that files can be formatted when setting the input language explicitly.
+ */
+ @Nested
+ class ExplicitLanguage {
+ /**
+ * Tests that a *.cjs file can be formatted when setting the input language
+ * explicitly.
+ */
+ @Test
+ void testSetLanguageCjs() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withLanguage("js").create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/js/fileBefore.cjs", "biome/js/fileAfter.cjs");
+ }
+
+ /**
+ * Tests that a *.css file can be formatted when setting the input language
+ * explicitly, using biome 1.8.3 which does require opt-in.
+ */
+ @Test
+ void testSetLanguageCssExperimental() {
+ var path = createBiomeConfig("biome/config/css-enabled.json");
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.8.3", downloadDir.toString()).withConfigPath(path).withLanguage("css").create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/css/fileBefore.css", "biome/css/fileAfter.css");
+ }
+
+ /**
+ * Tests that a *.css file can be formatted when setting the input language
+ * explicitly, using biome 1.9.0 which does not require opt-in.
+ */
+ @Test
+ void testSetLanguageCssStable() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.9.0", downloadDir.toString()).withLanguage("css").create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/css/fileBefore.css", "biome/css/fileAfter.css");
+ }
+
+ /**
+ * Tests that a *.cts file can be formatted when setting the input language
+ * explicitly.
+ */
+ @Test
+ void testSetLanguageCts() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withLanguage("ts").create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/ts/fileBefore.cts", "biome/ts/fileAfter.cts");
+ }
+
+ /**
+ * Tests that a *.js file can be formatted when setting the input language
+ * explicitly.
+ */
+ @Test
+ void testSetLanguageJs() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withLanguage("js").create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/js/fileBefore.js", "biome/js/fileAfter.js");
+ }
+
+ /**
+ * Tests that a *.json file can be formatted when setting the input language
+ * explicitly.
+ */
+ @Test
+ void testSetLanguageJson() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withLanguage("json").create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/json/fileBefore.json", "biome/json/fileAfter.json");
+ }
+
+ /**
+ * Tests that a *.jsonc file can be formatted when setting the input language
+ * explicitly.
+ */
+ @Test
+ void testSetLanguageJsonc() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withLanguage("jsonc").create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/jsonc/fileBefore.jsonc", "biome/jsonc/fileAfter.jsonc");
+ }
+
+ /**
+ * Tests that a *.jsx file can be formatted when setting the input language
+ * explicitly.
+ */
+ @Test
+ void testSetLanguageJsx() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withLanguage("jsx").create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/js/fileBefore.jsx", "biome/js/fileAfter.jsx");
+ }
+
+ /**
+ * Tests that a *.mjs file can be formatted without setting the input language
+ * explicitly.
+ */
+ @Test
+ void testSetLanguageMjs() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withLanguage("js").create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/js/fileBefore.mjs", "biome/js/fileAfter.mjs");
+ }
+
+ /**
+ * Tests that a *.mts file can be formatted when setting the input language
+ * explicitly.
+ */
+ @Test
+ void testSetLanguageMts() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withLanguage("ts").create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/ts/fileBefore.mts", "biome/ts/fileAfter.mts");
+ }
+
+ /**
+ * Tests that a *.ts file can be formatted when setting the input language
+ * explicitly.
+ */
+ @Test
+ void testSetLanguageTs() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withLanguage("ts").create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/ts/fileBefore.ts", "biome/ts/fileAfter.ts");
+ }
+
+ /**
+ * Tests that a *.tsx file can be formatted when setting the input language
+ * explicitly.
+ */
+ @Test
+ void testSetLanguageTsx() {
+ var step = BiomeStep.withExeDownload(BiomeFlavor.BIOME, "1.2.0", downloadDir.toString()).withLanguage("tsx").create();
+ var stepHarness = StepHarnessWithFile.forStep(BiomeStepTest.this, step);
+ stepHarness.testResource("biome/ts/fileBefore.tsx", "biome/ts/fileAfter.tsx");
+ }
+ }
+
+ private String createBiomeConfig(String name) {
+ var config = createTestFile(name).toPath();
+ var dir = config.getParent();
+ var rome = dir.resolve("biome.json");
+ ThrowingEx.run(() -> Files.copy(config, rome));
+ return dir.toString();
}
}