diff --git a/Cargo.lock b/Cargo.lock index 144bb37aaf2f33..20e4f8054ee01f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -85,6 +85,17 @@ dependencies = [ "aes", ] +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + [[package]] name = "ahash" version = "0.8.11" @@ -201,6 +212,12 @@ dependencies = [ "derive_arbitrary", ] +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + [[package]] name = "arrayvec" version = "0.7.4" @@ -487,6 +504,12 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" + [[package]] name = "bencher" version = "0.1.5" @@ -1366,6 +1389,7 @@ dependencies = [ "dprint-plugin-json", "dprint-plugin-jupyter", "dprint-plugin-markdown", + "dprint-plugin-toml", "dprint-plugin-typescript", "fancy-regex", "faster-hex", @@ -3118,6 +3142,20 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "dprint-plugin-toml" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a4db205d7c84101d1e4f6f56f51e50ccf81e528bd7f7eb2d38770f5e2f7259a" +dependencies = [ + "anyhow", + "dprint-core", + "dprint-core-macros", + "itertools 0.10.5", + "serde", + "taplo", +] + [[package]] name = "dprint-plugin-typescript" version = "0.93.3" @@ -4029,7 +4067,7 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "ahash", + "ahash 0.8.11", "allocator-api2", ] @@ -5093,6 +5131,29 @@ dependencies = [ "serde", ] +[[package]] +name = "logos" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf8b031682c67a8e3d5446840f9573eb7fe26efe7ec8d195c9ac4c0647c502f1" +dependencies = [ + "logos-derive", +] + +[[package]] +name = "logos-derive" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d849148dbaf9661a6151d1ca82b13bb4c4c128146a88d05253b38d4e2f496c" +dependencies = [ + "beef", + "fnv", + "proc-macro2", + "quote", + "regex-syntax 0.6.29", + "syn 1.0.109", +] + [[package]] name = "loom" version = "0.7.2" @@ -7688,7 +7749,7 @@ version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83406221c501860fce9c27444f44125eafe9e598b8b81be7563d7036784cd05c" dependencies = [ - "ahash", + "ahash 0.8.11", "anyhow", "dashmap", "once_cell", @@ -8151,6 +8212,26 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "taplo" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d22577122cf37c9aea9a9363f6f01bddaa1977617fe5abc59e221f23d114817" +dependencies = [ + "ahash 0.7.8", + "arc-swap", + "either", + "globset", + "itertools 0.10.5", + "logos", + "once_cell", + "rowan", + "serde_json", + "thiserror 1.0.69", + "time", + "tracing", +] + [[package]] name = "tar" version = "0.4.40" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 6d27d453de8903..fd141f224e477e 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -114,6 +114,7 @@ dotenvy = "0.15.7" dprint-plugin-json = "=0.19.4" dprint-plugin-jupyter = "=0.1.5" dprint-plugin-markdown = "=0.17.8" +dprint-plugin-toml = "=0.6.4" dprint-plugin-typescript = "=0.93.3" fancy-regex = "=0.10.0" faster-hex.workspace = true diff --git a/cli/tools/fmt.rs b/cli/tools/fmt.rs index f47ab57420a92d..852b29ed4bfb23 100644 --- a/cli/tools/fmt.rs +++ b/cli/tools/fmt.rs @@ -276,6 +276,7 @@ fn format_markdown( | "yml" | "yaml" | "sql" + | "toml" ) { // It's important to tell dprint proper file extension, otherwise // it might parse the file twice. @@ -305,6 +306,7 @@ fn format_markdown( } } "yml" | "yaml" => format_yaml(text, fmt_options), + "toml" => format_toml(text, fmt_options), "sql" => { if unstable_options.sql { format_sql(text, fmt_options) @@ -362,6 +364,38 @@ pub fn format_css( }) } +fn format_toml( + file_text: &str, + fmt_options: &FmtOptionsConfig, +) -> Result, AnyError> { + let ignore_file = file_text + .lines() + .take_while(|line| line.starts_with('#')) + .any(|line| { + line + .strip_prefix('#') + .unwrap() + .trim() + .starts_with("deno-fmt-ignore-file") + }); + + if ignore_file { + return Ok(None); + } + + let formatted_str = dprint_plugin_toml::format_text( + &PathBuf::from(""), + file_text, + &dprint_plugin_toml::configuration::ConfigurationBuilder::new() + .line_width(fmt_options.line_width.unwrap_or(80)) + .use_tabs(fmt_options.use_tabs.unwrap_or_default()) + .indent_width(fmt_options.indent_width.unwrap_or(2)) + .build(), + )?; + + Ok(formatted_str) +} + fn format_yaml( file_text: &str, fmt_options: &FmtOptionsConfig, @@ -590,6 +624,7 @@ pub fn format_file( } } "yml" | "yaml" => format_yaml(file_text, fmt_options), + "toml" => format_toml(file_text, fmt_options), "ipynb" => dprint_plugin_jupyter::format_text( file_text, |file_path: &Path, file_text: String| { @@ -1285,6 +1320,7 @@ fn is_supported_ext_fmt(path: &Path) -> bool { | "yaml" | "ipynb" | "sql" + | "toml" ) }) } diff --git a/tests/specs/fmt/toml/__test__.jsonc b/tests/specs/fmt/toml/__test__.jsonc new file mode 100644 index 00000000000000..5971c0f357c13f --- /dev/null +++ b/tests/specs/fmt/toml/__test__.jsonc @@ -0,0 +1,37 @@ +{ + "tempDir": true, + "tests": { + "badly_formatted": { + "args": "fmt badly_formatted.toml", + "output": "[WILDLINE]badly_formatted.toml\nChecked 1 file\n" + }, + "well_formatted": { + "args": "fmt --check well_formatted.toml", + "output": "Checked 1 file\n" + }, + "ignore_line": { + "args": "fmt --check ignore_line.toml", + "output": "Checked 1 file\n" + }, + "ignore_file": { + "args": "fmt ignore_file.toml", + "output": "Checked 1 file\n" + }, + "ignore_file2": { + "args": "fmt ignore_file2.toml", + "output": "Checked 1 file\n" + }, + "ignore_file3": { + "args": "fmt ignore_file3.toml", + "output": "Checked 1 file\n" + }, + "ignore_file4": { + "args": "fmt ignore_file4.toml", + "output": "Checked 1 file\n" + }, + "wrong_file_ignore": { + "args": "fmt wrong_file_ignore.toml", + "output": "wrong_file_ignore.out" + } + } +} diff --git a/tests/specs/fmt/toml/badly_formatted.toml b/tests/specs/fmt/toml/badly_formatted.toml new file mode 100644 index 00000000000000..66a55dcadf834a --- /dev/null +++ b/tests/specs/fmt/toml/badly_formatted.toml @@ -0,0 +1,15 @@ +[database] +enabled = true +ports = [ 8000, 8001, 8002 ] +data = [ ["delta", "phi"], [3.14] ] +temp_targets = { cpu = 79.5, case = 72.0 } + +[servers] + +[servers.alpha] +ip = "10.0.0.1" +role = "frontend" + +[servers.beta] +ip = "10.0.0.2" +role = "backend" \ No newline at end of file diff --git a/tests/specs/fmt/toml/ignore_file.toml b/tests/specs/fmt/toml/ignore_file.toml new file mode 100644 index 00000000000000..4e84c22a68742c --- /dev/null +++ b/tests/specs/fmt/toml/ignore_file.toml @@ -0,0 +1,2 @@ +# deno-fmt-ignore-file +enabled = true diff --git a/tests/specs/fmt/toml/ignore_file2.toml b/tests/specs/fmt/toml/ignore_file2.toml new file mode 100644 index 00000000000000..c39268e219bbce --- /dev/null +++ b/tests/specs/fmt/toml/ignore_file2.toml @@ -0,0 +1,2 @@ +#deno-fmt-ignore-file +enabled = true diff --git a/tests/specs/fmt/toml/ignore_file3.toml b/tests/specs/fmt/toml/ignore_file3.toml new file mode 100644 index 00000000000000..af131dd48089a0 --- /dev/null +++ b/tests/specs/fmt/toml/ignore_file3.toml @@ -0,0 +1,8 @@ +# Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor +# incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, +# quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +# deno-fmt-ignore-file + + + +enabled = true diff --git a/tests/specs/fmt/toml/ignore_file4.toml b/tests/specs/fmt/toml/ignore_file4.toml new file mode 100644 index 00000000000000..b21da94a350c62 --- /dev/null +++ b/tests/specs/fmt/toml/ignore_file4.toml @@ -0,0 +1,4 @@ +# deno-fmt-ignore-file Because this is templated yaml file + + +enabled = true diff --git a/tests/specs/fmt/toml/ignore_line.toml b/tests/specs/fmt/toml/ignore_line.toml new file mode 100644 index 00000000000000..8279b7ccc6622b --- /dev/null +++ b/tests/specs/fmt/toml/ignore_line.toml @@ -0,0 +1,2 @@ +# deno-fmt-ignore +enabled = true diff --git a/tests/specs/fmt/toml/well_formatted.toml b/tests/specs/fmt/toml/well_formatted.toml new file mode 100644 index 00000000000000..b57f45c63b55e2 --- /dev/null +++ b/tests/specs/fmt/toml/well_formatted.toml @@ -0,0 +1,15 @@ +[database] +enabled = true +ports = [8000, 8001, 8002] +data = [["delta", "phi"], [3.14]] +temp_targets = { cpu = 79.5, case = 72.0 } + +[servers] + +[servers.alpha] +ip = "10.0.0.1" +role = "frontend" + +[servers.beta] +ip = "10.0.0.2" +role = "backend" diff --git a/tests/specs/fmt/toml/wrong_file_ignore.out b/tests/specs/fmt/toml/wrong_file_ignore.out new file mode 100644 index 00000000000000..d7abbc1ca831cf --- /dev/null +++ b/tests/specs/fmt/toml/wrong_file_ignore.out @@ -0,0 +1,5 @@ +Error formatting: [WILDCARD]wrong_file_ignore.toml + Line 5, column 10: expected value + + enabled = +Checked 1 file diff --git a/tests/specs/fmt/toml/wrong_file_ignore.toml b/tests/specs/fmt/toml/wrong_file_ignore.toml new file mode 100644 index 00000000000000..22df005f405d71 --- /dev/null +++ b/tests/specs/fmt/toml/wrong_file_ignore.toml @@ -0,0 +1,5 @@ +# File ignore directive only works if it's in the first cluster +# of comment, ie. there are no empty lines after the first n-leading lines. + +# deno-fmt-ignore-file +enabled = \ No newline at end of file