fix(rome_cli): issue
MODIFY
crates/rome_cli/src/commands/format.rs
crates/rome_cli/src/commands/format.rs
@@ -71,15 +71,11 @@ pub(crate) fn apply_format_settings_from_cli(
let mut configuration = if let Some(configuration) = configuration {
configuration
} else {
- Configuration {
- formatter: Some(FormatterConfiguration::default()),
- javascript: Some(JavascriptConfiguration {
- formatter: Some(JavascriptFormatter::default()),
- globals: None,
- }),
- ..Configuration::default()
- }
+ Configuration::default()
};
+ let formatter = configuration
+ .formatter
+ .get_or_insert_with(FormatterConfiguration::default);
let size = session
.args
@@ -105,7 +101,6 @@ pub(crate) fn apply_format_settings_from_cli(
source,
})?;
- if let Some(formatter) = configuration.formatter.as_mut() {
match indent_style {
Some(IndentStyle::Tab) => {
formatter.indent_style = PlainIndentStyle::Tab;
@@ -120,7 +115,6 @@ pub(crate) fn apply_format_settings_from_cli(
if let Some(line_width) = line_width {
formatter.line_width = line_width;
}
- }
let quote_properties = session
.args
@@ -137,18 +131,20 @@ pub(crate) fn apply_format_settings_from_cli(
argument: "--quote-style",
source,
})?;
- if let Some(javascript) = configuration
+
+ let javascript = configuration
.javascript
- .as_mut()
- .and_then(|j| j.formatter.as_mut())
- {
+ .get_or_insert_with(JavascriptConfiguration::default);
+ let javascript_formatter = javascript
+ .formatter
+ .get_or_insert_with(JavascriptFormatter::default);
+
if let Some(quote_properties) = quote_properties {
- javascript.quote_properties = quote_properties;
+ javascript_formatter.quote_properties = quote_properties;
}
if let Some(quote_style) = quote_style {
- javascript.quote_style = quote_style;
- }
+ javascript_formatter.quote_style = quote_style;
}
Ok(configuration)

MODIFY
crates/rome_cli/tests/configs.rs
crates/rome_cli/tests/configs.rs
@@ -144,3 +144,19 @@ pub const CONFIG_INCORRECT_GLOBALS_V2: &str = r#"{
}
}
}"#;
+
+pub const CONFIG_ISSUE_3175_1: &str = r#"{
+ "formatter": {
+ "indentStyle": "space",
+ "indentSize": 2,
+ "lineWidth": 120
+ }
+}"#;
+
+pub const CONFIG_ISSUE_3175_2: &str = r#"{
+ "javascript": {
+ "formatter": {
+ "quoteStyle": "single"
+ }
+ }
+}"#;

MODIFY
crates/rome_cli/tests/main.rs
crates/rome_cli/tests/main.rs
@@ -734,7 +734,9 @@ mod ci {
mod format {
use super::*;
- use crate::configs::{CONFIG_DISABLED_FORMATTER, CONFIG_FORMAT};
+ use crate::configs::{
+ CONFIG_DISABLED_FORMATTER, CONFIG_FORMAT, CONFIG_ISSUE_3175_1, CONFIG_ISSUE_3175_2,
+ };
use crate::snap_test::markup_to_string;
use rome_console::markup;
use rome_fs::FileSystemExt;
@@ -934,6 +936,97 @@ mod format {
);
}
+ #[test]
+ fn applies_custom_configuration_over_config_file_issue_3175_v1() {
+ let mut fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_path = Path::new("rome.json");
+ fs.insert(file_path.into(), CONFIG_ISSUE_3175_1.as_bytes());
+
+ let file_path = Path::new("file.js");
+ fs.insert(file_path.into(), "import React from 'react';\n".as_bytes());
+
+ let result = run_cli(
+ DynRef::Borrowed(&mut fs),
+ DynRef::Borrowed(&mut console),
+ Arguments::from_vec(vec![
+ OsString::from("format"),
+ OsString::from("--quote-style"),
+ OsString::from("single"),
+ file_path.as_os_str().into(),
+ ]),
+ );
+
+ assert!(result.is_ok(), "run_cli returned {result:?}");
+
+ let mut file = fs
+ .open(file_path)
+ .expect("formatting target file was removed by the CLI");
+
+ let mut content = String::new();
+ file.read_to_string(&mut content)
+ .expect("failed to read file from memory FS");
+
+ assert_eq!(content, "import React from 'react';\n");
+
+ drop(file);
+ assert_cli_snapshot(
+ module_path!(),
+ "applies_custom_configuration_over_config_file_issue_3175_v1",
+ fs,
+ console,
+ );
+ }
+
+ #[test]
+ fn applies_custom_configuration_over_config_file_issue_3175_v2() {
+ let mut fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let source = r#"function f() {
+ return 'hey';
+}
+"#;
+
+ let file_path = Path::new("rome.json");
+ fs.insert(file_path.into(), CONFIG_ISSUE_3175_2.as_bytes());
+
+ let file_path = Path::new("file.js");
+ fs.insert(file_path.into(), source.as_bytes());
+
+ let result = run_cli(
+ DynRef::Borrowed(&mut fs),
+ DynRef::Borrowed(&mut console),
+ Arguments::from_vec(vec![
+ OsString::from("format"),
+ OsString::from("--indent-style"),
+ OsString::from("space"),
+ file_path.as_os_str().into(),
+ ]),
+ );
+
+ assert!(result.is_ok(), "run_cli returned {result:?}");
+
+ let mut file = fs
+ .open(file_path)
+ .expect("formatting target file was removed by the CLI");
+
+ let mut content = String::new();
+ file.read_to_string(&mut content)
+ .expect("failed to read file from memory FS");
+
+ assert_eq!(content, source);
+
+ drop(file);
+ assert_cli_snapshot(
+ module_path!(),
+ "applies_custom_configuration_over_config_file_issue_3175_v2",
+ fs,
+ console,
+ );
+ }
+
#[test]
fn applies_custom_quote_style() {
let mut fs = MemoryFileSystem::default();

ADD
crates/rome_cli/tests/snapshots/main_format/applies_custom_configuration_over_config_file_issue_3175_v1.snap
+---
+source: crates/rome_cli/tests/snap_test.rs
+expression: content
+---
+## `rome.json`
+
+```json
+{
+ "formatter": {
+ "indentStyle": "space",
+ "indentSize": 2,
+ "lineWidth": 120
+ }
+}
+```
+
+## `file.js`
+
+```js
+import React from 'react';
+
+```
+
+# Emitted Messages
+
+

ADD
crates/rome_cli/tests/snapshots/main_format/applies_custom_configuration_over_config_file_issue_3175_v2.snap
+---
+source: crates/rome_cli/tests/snap_test.rs
+expression: content
+---
+## `rome.json`
+
+```json
+{
+ "javascript": {
+ "formatter": {
+ "quoteStyle": "single"
+ }
+ }
+}
+```
+
+## `file.js`
+
+```js
+function f() {
+ return 'hey';
+}
+
+```
+
+# Emitted Messages
+
+

MODIFY
crates/rome_service/src/configuration/javascript.rs
crates/rome_service/src/configuration/javascript.rs
@@ -23,6 +23,15 @@ pub struct JavascriptConfiguration {
pub globals: Option<IndexSet<String>>,
}
+impl JavascriptConfiguration {
+ pub fn with_formatter() -> Self {
+ Self {
+ formatter: Some(JavascriptFormatter::default()),
+ ..JavascriptConfiguration::default()
+ }
+ }
+}
+
pub(crate) fn deserialize_globals<'de, D>(
deserializer: D,
) -> Result<Option<IndexSet<String>>, D::Error>

DELETE
npm/rome/tests/__snapshots__/wasm.test.mjs.snap
-// Vitest Snapshot v1
-
-exports[`Rome WebAssembly formatter > should not format and have diagnostics > syntax error 1`] = `
-[
- {
- "children": [],
- "code": "SyntaxError",
- "code_link": null,
- "file_id": 0,
- "footers": [],
- "primary": {
- "msg": [
- {
- "content": "",
- "elements": [],
- },
- ],
- "severity": "Error",
- "span": {
- "file": 0,
- "range": [
- 11,
- 12,
- ],
- },
- },
- "severity": "Error",
- "suggestions": [],
- "summary": null,
- "tag": null,
- "title": [
- {
- "content": "expected a name for the function in a function declaration, but found none",
- "elements": [],
- },
- ],
- },
-]
-`;

RENAME
npm/rome/tests/__snapshots__/daemon.test.mjs.snap
npm/rome/tests/daemon/__snapshots__/formatContent.test.mjs.snap
RENAME
npm/rome/tests/daemon.test.mjs
npm/rome/tests/daemon/formatContent.test.mjs
import { describe, expect, it } from "vitest";
-import { BackendKind, Rome } from "../dist";
+import { BackendKind, Rome } from "../../dist";
import { resolve } from "path";
import { fileURLToPath } from "url";
const target = process.env.CI ? "target/release/rome" : "target/debug/rome";
describe("Rome Deamon formatter", () => {
- it("should not format files", async () => {
- const pathToBinary = resolve(
- fileURLToPath(import.meta.url),
- "../../../..",
- target,
- );
-
- const rome = await Rome.create({
- backendKind: BackendKind.DAEMON,
- pathToBinary,
- });
-
- let result = await rome.formatFiles(["./path/to/file.js"]);
-
- expect(result.content).toEqual("");
- expect(result.diagnostics).toEqual([]);
- });
-
- it("should not format files in debug mode", async () => {
- const pathToBinary = resolve(
- fileURLToPath(import.meta.url),
- "../../../..",
- target,
- );
-
- const rome = await Rome.create({
- backendKind: BackendKind.DAEMON,
- pathToBinary,
- });
-
- let result = await rome.formatFiles(["./path/to/file.js"], {
- debug: true,
- });
-
- expect(result.content).toEqual("");
- expect(result.diagnostics).toEqual([]);
- expect(result.ir).toEqual("");
- });
-
it("should format content", async () => {
const command = resolve(
fileURLToPath(import.meta.url),
- "../../../..",
+ "../../../../..",
target,
);
@@ -67,7 +28,7 @@ describe("Rome Deamon formatter", () => {
it("should not format and have diagnostics", async () => {
const command = resolve(
fileURLToPath(import.meta.url),
- "../../../..",
+ "../../../../..",
target,
);
@@ -92,7 +53,7 @@ describe("Rome Deamon formatter", () => {
it("should format content in debug mode", async () => {
const command = resolve(
fileURLToPath(import.meta.url),
- "../../../..",
+ "../../../../..",
target,
);
@@ -116,7 +77,7 @@ describe("Rome Deamon formatter", () => {
it("should not format content with range", async () => {
const command = resolve(
fileURLToPath(import.meta.url),
- "../../../..",
+ "../../../../..",
target,
);
@@ -136,7 +97,7 @@ describe("Rome Deamon formatter", () => {
it("should not format content with range in debug mode", async () => {
const command = resolve(
fileURLToPath(import.meta.url),
- "../../../..",
+ "../../../../..",
target,
);
@@ -170,4 +131,4 @@ describe("Rome Deamon formatter", () => {
`,
);
});
-});
+}, 1500);

ADD
npm/rome/tests/daemon/formatFiles.test.mjs
+import { describe, expect, it } from "vitest";
+import { BackendKind, Rome } from "../../dist";
+import { resolve } from "path";
+import { fileURLToPath } from "url";
+
+const target = process.env.CI ? "target/release/rome" : "target/debug/rome";
+
+describe("Rome Deamon formatter", () => {
+ it("should not format files", async () => {
+ const pathToBinary = resolve(
+ fileURLToPath(import.meta.url),
+ "../../../../..",
+ target,
+ );
+
+ console.log(pathToBinary);
+
+ const rome = await Rome.create({
+ backendKind: BackendKind.DAEMON,
+ pathToBinary,
+ });
+
+ let result = await rome.formatFiles(["./path/to/file.js"]);
+
+ expect(result.content).toEqual("");
+ expect(result.diagnostics).toEqual([]);
+ });
+
+ it("should not format files in debug mode", async () => {
+ const pathToBinary = resolve(
+ fileURLToPath(import.meta.url),
+ "../../../../..",
+ target,
+ );
+
+ const rome = await Rome.create({
+ backendKind: BackendKind.DAEMON,
+ pathToBinary,
+ });
+
+ let result = await rome.formatFiles(["./path/to/file.js"], {
+ debug: true,
+ });
+
+ expect(result.content).toEqual("");
+ expect(result.diagnostics).toEqual([]);
+ expect(result.ir).toEqual("");
+ });
+});

DELETE
npm/rome/tests/wasm.test.mjs
-import { describe, it, expect } from "vitest";
-import { BackendKind, Rome } from "../dist";
-
-describe("Rome WebAssembly formatter", () => {
- it("should not format files", async () => {
- const rome = await Rome.create({
- backendKind: BackendKind.NODE,
- });
-
- let result = await rome.formatFiles(["./path/to/file.js"]);
-
- expect(result.content).toEqual("");
- expect(result.diagnostics).toEqual([]);
- });
-
- it("should not format files in debug mode", async () => {
- const rome = await Rome.create({
- backendKind: BackendKind.NODE,
- });
-
- let result = await rome.formatFiles(["./path/to/file.js"], {
- debug: true,
- });
-
- expect(result.content).toEqual("");
- expect(result.diagnostics).toEqual([]);
- expect(result.ir).toEqual("");
- });
-
- it("should format content", async () => {
- const rome = await Rome.create({
- backendKind: BackendKind.NODE,
- });
-
- let result = await rome.formatContent("function f () { }", {
- filePath: "example.js",
- });
-
- expect(result.content).toEqual("function f() {}\n");
- expect(result.diagnostics).toEqual([]);
- });
-
- it("should not format and have diagnostics", async () => {
- const rome = await Rome.create({
- backendKind: BackendKind.NODE,
- });
-
- let content = "function () { }";
- let result = await rome.formatContent(content, {
- filePath: "example.js",
- });
-
- expect(result.content).toEqual(content);
- expect(result.diagnostics).toHaveLength(1);
- expect(result.diagnostics[0].title[0].content).toContain(
- "expected a name for the function in a function declaration, but found none",
- );
- expect(result.diagnostics).toMatchSnapshot("syntax error");
- });
-
- it("should format content in debug mode", async () => {
- const rome = await Rome.create({
- backendKind: BackendKind.NODE,
- });
-
- let result = await rome.formatContent("function f() {}", {
- filePath: "example.js",
- debug: true,
- });
-
- expect(result.content).toEqual("function f() {}\n");
- expect(result.diagnostics).toEqual([]);
- expect(result.ir).toMatchInlineSnapshot(
- '"[\\"function\\", \\" \\", \\"f\\", group([\\"(\\", \\")\\"]), \\" \\", \\"{\\", \\"}\\", hard_line_break]"',
- );
- });
-
- it("should not format content with range", async () => {
- const rome = await Rome.create({
- backendKind: BackendKind.NODE,
- });
-
- let result = await rome.formatContent("let a ; function g () { }", {
- filePath: "file.js",
- range: [20, 25],
- });
-
- expect(result.content).toEqual("function g() {}");
- expect(result.diagnostics).toEqual([]);
- });
-
- it("should not format content with range in debug mode", async () => {
- const rome = await Rome.create({
- backendKind: BackendKind.NODE,
- });
-
- let result = await rome.formatContent("let a ; function g () { }", {
- filePath: "file.js",
- range: [20, 25],
- debug: true,
- });
-
- expect(result.content).toEqual("function g() {}");
- expect(result.diagnostics).toEqual([]);
- expect(result.ir).toMatchInlineSnapshot(
- `
- "[
- group([\\"let\\", \\" \\", \\"a\\"]),
- \\";\\",
- hard_line_break,
- \\"function\\",
- \\" \\",
- \\"g\\",
- group([\\"(\\", \\")\\"]),
- \\" \\",
- \\"{\\",
- \\"}\\",
- hard_line_break
- ]"
- `,
- );
- });
-});
-
-describe("Rome parser", () => {
- it("should not parse content", async () => {
- const rome = await Rome.create({
- backendKind: BackendKind.NODE,
- });
-
- let result = await rome.parseContent("function f() {}", {
- filePath: "example.js",
- });
-
- expect(result.ast).toEqual("");
- expect(result.cst).toEqual("");
- expect(result.diagnostics).toEqual([]);
- });
-});

fix(rome_cli): issue #3175 (#3189)