From b5fe3185af86813b0e1d93e390be2b6a8a3d8801 Mon Sep 17 00:00:00 2001 From: Mads Hougesen Date: Thu, 21 Mar 2024 02:05:26 +0100 Subject: [PATCH] feat(ruby): add support for rufo (#100) --- .github/workflows/validate.yml | 3 +++ README.md | 2 +- schemas/v0.0.2/mdsf.schema.json | 6 ++--- src/formatters/mod.rs | 23 ++++++++++-------- src/formatters/rufo.rs | 43 +++++++++++++++++++++++++++++++++ src/languages/java.rs | 4 +-- src/languages/ruby.rs | 34 ++++++++++++++++++++++++-- 7 files changed, 97 insertions(+), 18 deletions(-) create mode 100644 src/formatters/rufo.rs diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 7b25e73c..6f25ca13 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -197,5 +197,8 @@ jobs: - name: ktlint run: curl -sSLO https://github.com/pinterest/ktlint/releases/download/1.2.1/ktlint && chmod a+x ktlint && sudo mv ktlint /usr/local/bin/ + - name: rufo + run: gem install rufo + - name: run tests run: cargo test diff --git a/README.md b/README.md index 2a7e3461..b88f345b 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ mdsf init | Python | `autopep8`, `black`, `blue`, `isort`, `ruff`, `usort`, `yapf` | | ReScript | `rescript_format` | | Roc | `roc_format` | -| Ruby | `rubocop` | +| Ruby | `rubocop`, `rufo` | | Rust | `rustfmt` | | Scala | `scalafmt` | | Shell | `beautysh`, `shfmt` | diff --git a/schemas/v0.0.2/mdsf.schema.json b/schemas/v0.0.2/mdsf.schema.json index 6488f2e7..c996dcc9 100644 --- a/schemas/v0.0.2/mdsf.schema.json +++ b/schemas/v0.0.2/mdsf.schema.json @@ -182,7 +182,7 @@ "java": { "default": { "enabled": true, - "formatter": ["google-java-format", "clang-format"] + "formatter": [["google-java-format", "clang-format"]] }, "allOf": [ { @@ -361,7 +361,7 @@ "ruby": { "default": { "enabled": true, - "formatter": "rubocop" + "formatter": [["rubocop", "rufo"]] }, "allOf": [ { @@ -1686,7 +1686,7 @@ }, "Ruby": { "type": "string", - "enum": ["rubocop"] + "enum": ["rubocop", "rufo"] }, "Rust": { "type": "string", diff --git a/src/formatters/mod.rs b/src/formatters/mod.rs index aa24b86e..94fd55c4 100644 --- a/src/formatters/mod.rs +++ b/src/formatters/mod.rs @@ -38,6 +38,7 @@ pub mod rescript_format; pub mod roc_format; pub mod rubocop; pub mod ruff; +pub mod rufo; pub mod rustfmt; pub mod scalafmt; pub mod shfmt; @@ -52,16 +53,18 @@ pub mod zigfmt; #[inline] pub fn setup_snippet(code: &str, file_ext: &str) -> std::io::Result { - let mut b = tempfile::Builder::new(); - - b.rand_bytes(12).suffix(file_ext); - - // ktlint wants PascalCase file names - if file_ext == Language::Kotlin.to_file_ext() { - b.prefix("MdsfFile"); - } - - let mut f = b.tempfile()?; + let mut f = tempfile::Builder::new() + .rand_bytes(12) + .suffix(file_ext) + .prefix( + // ktlint wants PascalCase file names + if file_ext == Language::Kotlin.to_file_ext() { + "MdsfFile" + } else { + "mdsf" + }, + ) + .tempfile()?; f.write_all(code.as_bytes())?; f.flush()?; diff --git a/src/formatters/rufo.rs b/src/formatters/rufo.rs new file mode 100644 index 00000000..5679e101 --- /dev/null +++ b/src/formatters/rufo.rs @@ -0,0 +1,43 @@ +use super::execute_command; + +#[inline] +pub fn format_using_rufo( + snippet_path: &std::path::Path, +) -> std::io::Result<(bool, Option)> { + let mut cmd = std::process::Command::new("rufo"); + + cmd.arg("--simple-exit").arg(snippet_path); + + execute_command(&mut cmd, snippet_path) +} + +#[cfg(test)] +mod test_rufo { + use crate::{ + formatters::{rufo::format_using_rufo, setup_snippet}, + languages::Language, + }; + + #[test_with::executable(rufo)] + #[test] + fn it_should_format_ruby() { + let input = "def add( a , b ) + return a + b + end"; + + let expected_output = "def add(a, b) + return a + b +end +"; + + let snippet = setup_snippet(input, Language::Ruby.to_file_ext()) + .expect("it to create a snippet file"); + + let output = format_using_rufo(snippet.path()) + .expect("it to be successful") + .1 + .expect("it to be some"); + + assert_eq!(expected_output, output); + } +} diff --git a/src/languages/java.rs b/src/languages/java.rs index 84f1f7e4..ddbb23ae 100644 --- a/src/languages/java.rs +++ b/src/languages/java.rs @@ -30,10 +30,10 @@ impl Default for Lang { impl Default for MdsfFormatter { #[inline] fn default() -> Self { - Self::Multiple(vec![ + Self::Multiple(vec![Self::Multiple(vec![ Self::Single(Java::GoogleJavaFormat), Self::Single(Java::ClangFormat), - ]) + ])]) } } diff --git a/src/languages/ruby.rs b/src/languages/ruby.rs index d4b0a87a..b8b22d53 100644 --- a/src/languages/ruby.rs +++ b/src/languages/ruby.rs @@ -1,6 +1,6 @@ use schemars::JsonSchema; -use crate::formatters::{rubocop::format_using_rubocop, MdsfFormatter}; +use crate::formatters::{rubocop::format_using_rubocop, rufo::format_using_rufo, MdsfFormatter}; use super::{Lang, LanguageFormatter}; @@ -10,6 +10,8 @@ pub enum Ruby { #[default] #[serde(rename = "rubocop")] RuboCop, + #[serde(rename = "rufo")] + Rufo, } impl Default for Lang { @@ -25,7 +27,10 @@ impl Default for Lang { impl Default for MdsfFormatter { #[inline] fn default() -> Self { - Self::Single(Ruby::RuboCop) + Self::Multiple(vec![Self::Multiple(vec![ + Self::Single(Ruby::RuboCop), + Self::Single(Ruby::Rufo), + ])]) } } @@ -37,6 +42,7 @@ impl LanguageFormatter for Ruby { ) -> std::io::Result<(bool, Option)> { match self { Self::RuboCop => format_using_rubocop(snippet_path), + Self::Rufo => format_using_rufo(snippet_path), } } } @@ -99,4 +105,28 @@ end assert_eq!(output, expected_output); } + + #[test_with::executable(rufo)] + #[test] + fn test_rufo() { + let expected_output = "def add(a, b) + return a + b +end +"; + + let l = Lang:: { + enabled: true, + formatter: MdsfFormatter::Single(Ruby::Rufo), + }; + + let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file"); + let snippet_path = snippet.path(); + + let output = l + .format(snippet_path) + .expect("it to not fail") + .expect("it to be a snippet"); + + assert_eq!(output, expected_output); + } }