From 851c252c8015001273238ee196852f530481189d Mon Sep 17 00:00:00 2001 From: Mads Hougesen Date: Sat, 23 Mar 2024 17:05:02 +0100 Subject: [PATCH] feat(csharp): add support for csharpier (#130) * feat(csharp): add support for csharpier * ci: install csharpier and fantomas --- .github/workflows/validate.yml | 6 ++++ .gitignore | 2 ++ README.md | 2 +- schemas/v0.0.2/mdsf.schema.json | 4 +-- src/formatters/csharpier.rs | 55 +++++++++++++++++++++++++++++++++ src/formatters/mod.rs | 32 ++++++++++--------- src/formatters/usort.rs | 2 +- src/languages/csharp.rs | 52 +++++++++++++++++++++++++++---- 8 files changed, 131 insertions(+), 24 deletions(-) create mode 100644 src/formatters/csharpier.rs diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index c46b979..77c029f 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -206,5 +206,11 @@ jobs: - name: standardrb run: gem install standardrb + - name: fantomas + run: dotnet tool install -g fantomas + + - name: csharpier + run: dotnet tool install -g csharpier + - name: run tests run: cargo test diff --git a/.gitignore b/.gitignore index ea8c4bf..e7ddc3e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ /target + +.mdsf-cache diff --git a/README.md b/README.md index 5c4d932..b16a517 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ mdsf init | ---------- | ------------------------------------------------------------- | | Blade | `blade-formatter` | | C | `clang-format` | -| CSharp | `clang-format` | +| CSharp | `clang-format`, `csharpier` | | Clojure | `cljstyle` | | Cpp | `clang-format` | | Crystal | `crystal_format` | diff --git a/schemas/v0.0.2/mdsf.schema.json b/schemas/v0.0.2/mdsf.schema.json index 2614022..9a9a322 100644 --- a/schemas/v0.0.2/mdsf.schema.json +++ b/schemas/v0.0.2/mdsf.schema.json @@ -61,7 +61,7 @@ "csharp": { "default": { "enabled": true, - "formatter": "clang-format" + "formatter": [["csharpier", "clang-format"]] }, "allOf": [ { @@ -524,7 +524,7 @@ }, "CSharp": { "type": "string", - "enum": ["clang-format"] + "enum": ["csharpier", "clang-format"] }, "Clojure": { "type": "string", diff --git a/src/formatters/csharpier.rs b/src/formatters/csharpier.rs new file mode 100644 index 0000000..da19118 --- /dev/null +++ b/src/formatters/csharpier.rs @@ -0,0 +1,55 @@ +use super::execute_command; + +#[inline] +pub fn format_using_csharpier( + snippet_path: &std::path::Path, +) -> std::io::Result<(bool, Option)> { + let mut cmd = std::process::Command::new("dotnet"); + + cmd.arg("csharpier").arg(snippet_path); + + execute_command(&mut cmd, snippet_path) +} + +#[cfg(test)] +mod test_csharpier { + use crate::{formatters::setup_snippet, languages::Language}; + + use super::format_using_csharpier; + + #[test_with::executable(dotnet)] + #[test] + fn it_should_format_csharp() { + let input = "namespace Mdsf { + class Adder { + public static int add(int a,int b) { + var c=a+b ; + return c ; + } + } + } "; + + let expected_output = "namespace Mdsf +{ + class Adder + { + public static int add(int a, int b) + { + var c = a + b; + return c; + } + } +} +"; + + let snippet = setup_snippet(input, Language::CSharp.to_file_ext()) + .expect("it to create a snippet file"); + + let output = format_using_csharpier(snippet.path()) + .expect("it to be successful") + .1 + .expect("it to be some"); + + assert_eq!(output, expected_output); + } +} diff --git a/src/formatters/mod.rs b/src/formatters/mod.rs index a2111d8..8aba955 100644 --- a/src/formatters/mod.rs +++ b/src/formatters/mod.rs @@ -14,6 +14,7 @@ pub mod blue; pub mod clang_format; pub mod cljstyle; pub mod crystal_format; +pub mod csharpier; pub mod dart_format; pub mod deno_fmt; pub mod efmt; @@ -63,20 +64,23 @@ pub mod zigfmt; #[inline] pub fn setup_snippet(code: &str, file_ext: &str) -> std::io::Result { - let _ = std::fs::create_dir_all(".mdsf-cache"); - - 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_in(".mdsf-cache")?; + let mut b = tempfile::Builder::new(); + + b.rand_bytes(12).suffix(file_ext).prefix( + // ktlint wants PascalCase file names + if file_ext == Language::Kotlin.to_file_ext() { + "MdsfFile" + } else { + "mdsf" + }, + ); + + let mut f = if file_ext == ".cs" { + let _ = std::fs::create_dir_all(".mdsf-cache"); + b.tempfile_in(".mdsf-cache") + } else { + b.tempfile() + }?; f.write_all(code.as_bytes())?; f.flush()?; diff --git a/src/formatters/usort.rs b/src/formatters/usort.rs index 40731f1..f1b4de2 100644 --- a/src/formatters/usort.rs +++ b/src/formatters/usort.rs @@ -12,7 +12,7 @@ pub fn format_using_usort( } #[cfg(test)] -mod test_isort { +mod test_usort { use crate::{formatters::setup_snippet, languages::Language}; use super::format_using_usort; diff --git a/src/languages/csharp.rs b/src/languages/csharp.rs index 956b4d0..2ce1cf2 100644 --- a/src/languages/csharp.rs +++ b/src/languages/csharp.rs @@ -1,6 +1,8 @@ use schemars::JsonSchema; -use crate::formatters::{clang_format::format_using_clang_format, MdsfFormatter}; +use crate::formatters::{ + clang_format::format_using_clang_format, csharpier::format_using_csharpier, MdsfFormatter, +}; use super::{Lang, LanguageFormatter}; @@ -8,6 +10,8 @@ use super::{Lang, LanguageFormatter}; #[cfg_attr(test, derive(PartialEq, Eq))] pub enum CSharp { #[default] + #[serde(rename = "csharpier")] + CSharpier, #[serde(rename = "clang-format")] ClangFormat, } @@ -25,7 +29,10 @@ impl Default for Lang { impl Default for MdsfFormatter { #[inline] fn default() -> Self { - Self::Single(CSharp::ClangFormat) + Self::Multiple(vec![Self::Multiple(vec![ + Self::Single(CSharp::CSharpier), + Self::Single(CSharp::ClangFormat), + ])]) } } @@ -36,6 +43,7 @@ impl LanguageFormatter for CSharp { snippet_path: &std::path::Path, ) -> std::io::Result<(bool, Option)> { match self { + Self::CSharpier => format_using_csharpier(snippet_path), Self::ClangFormat => format_using_clang_format(snippet_path), } } @@ -53,8 +61,8 @@ mod test_csharp { const INPUT: &str = "namespace Mdsf { class Adder { public static int add(int a,int b) { - a-b ; - return a + b; + var c = a+b ; + return c; } } } "; @@ -99,12 +107,44 @@ mod test_csharp { let expected_output = "namespace Mdsf { class Adder { public static int add(int a, int b) { - a - b; - return a + b; + var c = a + b; + return c; } } }"; assert_eq!(output, expected_output); } + + #[test_with::executable(dotnet)] + #[test] + fn test_csharpier() { + let l = Lang:: { + enabled: true, + formatter: MdsfFormatter::Single(CSharp::CSharpier), + }; + + 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"); + + let expected_output = "namespace Mdsf +{ + class Adder + { + public static int add(int a, int b) + { + var c = a + b; + return c; + } + } +} +"; + + assert_eq!(output, expected_output); + } }