Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(kcl): support kcl fmt #185

Merged
merged 1 commit into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ mdsf init
| Json | `biome`, `clang-format`, `deno_fmt`, `prettier` |
| Julia | `juliaformatter.jl` |
| Just | `just_fmt` |
| Kcl | `kcl_fmt` |
| Kotlin | `ktfmt`, `ktlint` |
| Lua | `luaformatter`, `stylua` |
| Markdown | `prettier` |
Expand Down
4 changes: 4 additions & 0 deletions mdsf.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@
"enabled": true,
"formatter": "just_fmt"
},
"kcl": {
"enabled": true,
"formatter": "kcl_fmt"
},
"kotlin": {
"enabled": true,
"formatter": [["ktlint", "ktfmt"]]
Expand Down
40 changes: 40 additions & 0 deletions schemas/v0.0.3/mdsf.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,17 @@
}
]
},
"kcl": {
"default": {
"enabled": true,
"formatter": "kcl_fmt"
},
"allOf": [
{
"$ref": "#/definitions/Lang_for_Kcl"
}
]
},
"kotlin": {
"default": {
"enabled": true,
Expand Down Expand Up @@ -691,6 +702,10 @@
"type": "string",
"enum": ["just_fmt"]
},
"Kcl": {
"type": "string",
"enum": ["kcl_fmt"]
},
"Kotlin": {
"type": "string",
"enum": ["ktlint", "ktfmt"]
Expand Down Expand Up @@ -1007,6 +1022,18 @@
}
}
},
"Lang_for_Kcl": {
"type": "object",
"required": ["enabled", "formatter"],
"properties": {
"enabled": {
"type": "boolean"
},
"formatter": {
"$ref": "#/definitions/MdsfFormatter_for_Kcl"
}
}
},
"Lang_for_Kotlin": {
"type": "object",
"required": ["enabled", "formatter"],
Expand Down Expand Up @@ -1653,6 +1680,19 @@
}
]
},
"MdsfFormatter_for_Kcl": {
"anyOf": [
{
"$ref": "#/definitions/Kcl"
},
{
"type": "array",
"items": {
"$ref": "#/definitions/MdsfFormatter_for_Kcl"
}
}
]
},
"MdsfFormatter_for_Kotlin": {
"anyOf": [
{
Expand Down
8 changes: 6 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use crate::{
csharp::CSharp, css::Css, dart::Dart, elixir::Elixir, elm::Elm, erlang::Erlang,
fortran::Fortran, fsharp::FSharp, gleam::Gleam, go::Go, graphql::GraphQL, groovy::Groovy,
haskell::Haskell, hcl::Hcl, html::Html, java::Java, javascript::JavaScript, json::Json,
julia::Julia, just::Just, kotlin::Kotlin, lua::Lua, markdown::Markdown, nim::Nim, nix::Nix,
objective_c::ObjectiveC, ocaml::OCaml, perl::Perl, protobuf::Protobuf,
julia::Julia, just::Just, kcl::Kcl, kotlin::Kotlin, lua::Lua, markdown::Markdown, nim::Nim,
nix::Nix, objective_c::ObjectiveC, ocaml::OCaml, perl::Perl, protobuf::Protobuf,
purescript::PureScript, python::Python, rescript::ReScript, roc::Roc, ruby::Ruby,
rust::Rust, scala::Scala, shell::Shell, sql::Sql, swift::Swift, toml::Toml,
typescript::TypeScript, vue::Vue, xml::Xml, yaml::Yaml, zig::Zig, Lang,
Expand Down Expand Up @@ -118,6 +118,9 @@ pub struct MdsfConfig {
#[serde(default)]
pub just: Lang<Just>,

#[serde(default)]
pub kcl: Lang<Kcl>,

#[serde(default)]
pub kotlin: Lang<Kotlin>,

Expand Down Expand Up @@ -228,6 +231,7 @@ impl Default for MdsfConfig {
json: Lang::<Json>::default(),
julia: Lang::<Julia>::default(),
just: Lang::<Just>::default(),
kcl: Lang::<Kcl>::default(),
kotlin: Lang::<Kotlin>::default(),
lua: Lang::<Lua>::default(),
markdown: Lang::<Markdown>::default(),
Expand Down
71 changes: 71 additions & 0 deletions src/formatters/kcl_fmt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use super::execute_command;
use crate::error::MdsfError;

#[inline]
pub fn format_using_kcl_fmt(
snippet_path: &std::path::Path,
) -> Result<(bool, Option<String>), MdsfError> {
let mut cmd = std::process::Command::new("kcl");

cmd.arg("fmt").arg(snippet_path);

execute_command(&mut cmd, snippet_path)
}

#[cfg(test)]
mod test_kcl_fmt {
use super::format_using_kcl_fmt;
use crate::{formatters::setup_snippet, languages::Language};

#[test_with::executable(kcl)]
#[test]
fn it_should_format_kcl() {
let input = r#"apiVersion = "apps/v1"
kind = "Deployment"
metadata = {
name = "nginx"
labels.app = "nginx"
}
spec = {
replicas = 3
selector.matchLabels = metadata.labels
template.metadata.labels = metadata.labels
template.spec.containers = [
{
name = metadata.name
image = "${metadata.name}:1.14.2"
ports = [{ containerPort = 80 }]
}
]
}
"#;

let expected_output = r#"apiVersion = "apps/v1"
kind = "Deployment"
metadata = {
name = "nginx"
labels.app = "nginx"
}
spec = {
replicas = 3
selector.matchLabels = metadata.labels
template.metadata.labels = metadata.labels
template.spec.containers = [{
name = metadata.name
image = "${metadata.name}:1.14.2"
ports = [{containerPort = 80}]
}]
}
"#;

let snippet =
setup_snippet(input, Language::Kcl.to_file_ext()).expect("it to create a snippet file");

let output = format_using_kcl_fmt(snippet.path())
.expect("it to be successful")
.1
.expect("it to be some");

assert_eq!(expected_output, output);
}
}
2 changes: 2 additions & 0 deletions src/formatters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub mod hindent;
pub mod isort;
pub mod juliaformatter_jl;
pub mod just_fmt;
pub mod kcl_fmt;
pub mod ktfmt;
pub mod ktlint;
pub mod luaformatter;
Expand Down Expand Up @@ -189,6 +190,7 @@ pub fn format_snippet(config: &MdsfConfig, info: &LineInfo, code: &str) -> Strin
Language::Json(_flavor) => config.json.format(snippet_path, info),
Language::Julia => config.julia.format(snippet_path, info),
Language::Just => config.just.format(snippet_path, info),
Language::Kcl => config.kcl.format(snippet_path, info),
Language::Kotlin => config.kotlin.format(snippet_path, info),
Language::Lua => config.lua.format(snippet_path, info),
Language::Markdown => config.markdown.format(snippet_path, info),
Expand Down
141 changes: 141 additions & 0 deletions src/languages/kcl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
use schemars::JsonSchema;

use super::{Lang, LanguageFormatter};
use crate::{
error::MdsfError,
formatters::{kcl_fmt::format_using_kcl_fmt, MdsfFormatter},
};

#[derive(Default, serde::Serialize, serde::Deserialize, JsonSchema)]
#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
pub enum Kcl {
#[default]
#[serde(rename = "kcl_fmt")]
KclFmt,
}

impl Default for Lang<Kcl> {
#[inline]
fn default() -> Self {
Self {
enabled: true,
formatter: MdsfFormatter::<Kcl>::default(),
}
}
}

impl Default for MdsfFormatter<Kcl> {
#[inline]
fn default() -> Self {
Self::Single(Kcl::KclFmt)
}
}

impl LanguageFormatter for Kcl {
#[inline]
fn format_snippet(
&self,
snippet_path: &std::path::Path,
) -> Result<(bool, Option<String>), MdsfError> {
match self {
Self::KclFmt => format_using_kcl_fmt(snippet_path),
}
}
}

impl core::fmt::Display for Kcl {
#[inline]
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::KclFmt => write!(f, "kcl_fmt"),
}
}
}

#[cfg(test)]
mod test_kcl {
use super::Kcl;
use crate::{
formatters::{setup_snippet, MdsfFormatter},
languages::Lang,
LineInfo,
};

const INPUT: &str = r#"apiVersion = "apps/v1"
kind = "Deployment"
metadata = {
name = "nginx"
labels.app = "nginx"
}
spec = {
replicas = 3
selector.matchLabels = metadata.labels
template.metadata.labels = metadata.labels
template.spec.containers = [
{
name = metadata.name
image = "${metadata.name}:1.14.2"
ports = [{ containerPort = 80 }]
}
]
}
"#;
const EXTENSION: &str = crate::languages::Language::Kcl.to_file_ext();

#[test]
fn it_should_be_enabled_by_default() {
assert!(Lang::<Kcl>::default().enabled);
}

#[test]
fn it_should_not_format_when_enabled_is_false() {
let l = Lang::<Kcl> {
enabled: false,
formatter: MdsfFormatter::Single(Kcl::KclFmt),
};

let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file");
let snippet_path = snippet.path();

assert!(l
.format(snippet_path, &LineInfo::fake())
.expect("it to not fail")
.is_none());
}

#[test_with::executable(kcl)]
#[test]
fn test_kcl_fmt() {
let l = Lang::<Kcl> {
enabled: true,
formatter: MdsfFormatter::Single(Kcl::KclFmt),
};

let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file");
let snippet_path = snippet.path();

let output = l
.format(snippet_path, &LineInfo::fake())
.expect("it to not fail")
.expect("it to be a snippet");

let expected_output = r#"apiVersion = "apps/v1"
kind = "Deployment"
metadata = {
name = "nginx"
labels.app = "nginx"
}
spec = {
replicas = 3
selector.matchLabels = metadata.labels
template.metadata.labels = metadata.labels
template.spec.containers = [{
name = metadata.name
image = "${metadata.name}:1.14.2"
ports = [{containerPort = 80}]
}]
}
"#;
assert_eq!(output, expected_output);
}
}
5 changes: 5 additions & 0 deletions src/languages/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub mod javascript;
pub mod json;
pub mod julia;
pub mod just;
pub mod kcl;
pub mod kotlin;
pub mod lua;
pub mod markdown;
Expand Down Expand Up @@ -174,6 +175,7 @@ pub enum Language {
Json(JsonFlavor),
Julia,
Just,
Kcl,
Kotlin,
Lua,
Markdown,
Expand Down Expand Up @@ -236,6 +238,7 @@ impl core::fmt::Display for Language {
Self::Json(flavor) => flavor.fmt(f),
Self::Julia => f.write_str("julia"),
Self::Just => f.write_str("just"),
Self::Kcl => f.write_str("kcl"),
Self::Kotlin => f.write_str("kotlin"),
Self::Lua => f.write_str("lua"),
Self::Markdown => f.write_str("markdown"),
Expand Down Expand Up @@ -307,6 +310,7 @@ impl Language {
"json5" => Some(Self::Json(JsonFlavor::Json5)),
"julia" | "jl" => Some(Self::Julia),
"just" | "justfile" => Some(Self::Just),
"kcl" => Some(Self::Kcl),
"kotlin" => Some(Self::Kotlin),
"lua" => Some(Self::Lua),
"markdown" | "md" => Some(Self::Markdown),
Expand Down Expand Up @@ -376,6 +380,7 @@ impl Language {
Self::Json(JsonFlavor::Json5) => ".json5",
Self::Julia => ".jl",
Self::Just => ".justfile",
Self::Kcl => ".kcl",
Self::Kotlin => ".kt",
Self::Lua => ".lua",
Self::Markdown => ".md",
Expand Down
Loading