Skip to content

Commit

Permalink
feat(php): support blade-formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
hougesen committed Mar 18, 2024
1 parent 9b4298c commit 06a8fae
Show file tree
Hide file tree
Showing 7 changed files with 316 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ mdsf init
| Language | Formatters |
| ----------- | ------------------------------------------------------------- |
| Blade | `blade-formatter` |
| C | `clang-format` |
| Cpp | `clang-format` |
| Crystal | `crystal_format` |
Expand Down
40 changes: 40 additions & 0 deletions schemas/v0.0.1/mdsf.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@
"title": "MdsfConfig",
"type": "object",
"properties": {
"blade": {
"default": {
"enabled": true,
"formatter": "blade-formatter"
},
"allOf": [
{
"$ref": "#/definitions/Lang_for_Blade"
}
]
},
"c": {
"default": {
"enabled": true,
Expand Down Expand Up @@ -360,6 +371,10 @@
}
},
"definitions": {
"Blade": {
"type": "string",
"enum": ["blade-formatter"]
},
"C": {
"type": "string",
"enum": ["clang-format"]
Expand Down Expand Up @@ -424,6 +439,18 @@
"type": "string",
"enum": ["just_fmt"]
},
"Lang_for_Blade": {
"type": "object",
"required": ["enabled", "formatter"],
"properties": {
"enabled": {
"type": "boolean"
},
"formatter": {
"$ref": "#/definitions/MdsfFormatter_for_Blade"
}
}
},
"Lang_for_C": {
"type": "object",
"required": ["enabled", "formatter"],
Expand Down Expand Up @@ -816,6 +843,19 @@
"type": "string",
"enum": ["prettier"]
},
"MdsfFormatter_for_Blade": {
"anyOf": [
{
"$ref": "#/definitions/Blade"
},
{
"type": "array",
"items": {
"$ref": "#/definitions/MdsfFormatter_for_Blade"
}
}
]
},
"MdsfFormatter_for_C": {
"anyOf": [
{
Expand Down
8 changes: 6 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use schemars::JsonSchema;

use crate::languages::{
c::C, cpp::Cpp, crystal::Crystal, csharp::CSharp, css::Css, dart::Dart, elixir::Elixir,
elm::Elm, gleam::Gleam, go::Go, graphql::GraphQL, html::Html, java::Java,
blade::Blade, c::C, cpp::Cpp, crystal::Crystal, csharp::CSharp, css::Css, dart::Dart,
elixir::Elixir, elm::Elm, gleam::Gleam, go::Go, graphql::GraphQL, html::Html, java::Java,
javascript::JavaScript, json::Json, just::Just, lua::Lua, markdown::Markdown, nim::Nim,
objective_c::ObjectiveC, protobuf::Protobuf, python::Python, roc::Roc, ruby::Ruby, rust::Rust,
shell::Shell, sql::Sql, toml::Toml, typescript::TypeScript, vue::Vue, yaml::Yaml, zig::Zig,
Expand All @@ -16,6 +16,9 @@ pub struct MdsfConfig {
#[serde(rename = "$schema", default = "default_schema_location")]
pub schema: String,

#[serde(default)]
pub blade: Lang<Blade>,

#[serde(default)]
pub c: Lang<C>,

Expand Down Expand Up @@ -119,6 +122,7 @@ impl Default for MdsfConfig {
Self {
schema: default_schema_location(),

blade: Lang::<Blade>::default(),
c: Lang::<C>::default(),
cpp: Lang::<Cpp>::default(),
crystal: Lang::<Crystal>::default(),
Expand Down
109 changes: 109 additions & 0 deletions src/formatters/blade_formatter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
use crate::runners::{setup_npm_script, JavaScriptRuntime};

use super::execute_command;

#[inline]
fn set_blade_formatter_args(cmd: &mut std::process::Command, snippet_path: &std::path::Path) {
cmd.arg("--write").arg(snippet_path);
}

#[inline]
fn invote_blade_formatter(
mut cmd: std::process::Command,
snippet_path: &std::path::Path,
) -> std::io::Result<(bool, Option<String>)> {
set_blade_formatter_args(&mut cmd, snippet_path);

execute_command(&mut cmd, snippet_path)
}

#[inline]
pub fn format_using_blade_formatter(
snippet_path: &std::path::Path,
) -> std::io::Result<(bool, Option<String>)> {
invote_blade_formatter(
setup_npm_script(JavaScriptRuntime::default(), "blade-formatter"),
snippet_path,
)
}

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

#[test]
fn it_should_format_blade() {
let input = r#"@extends('frontend.layouts.app')
@section('title') foo
@endsection
@section('content')
<section id="content">
<div class="container mod-users-pd-h">
<div class="pf-user-header">
<div></div>
<p>@lang('users.index')</p>
</div>
<div class="pf-users-branch">
<ul class="pf-users-branch__list">
@foreach($users as $user)
<li>
<img src="{{ asset('img/frontend/icon/branch-arrow.svg') }}" alt="branch_arrow">
{{ link_to_route("frontend.users.user.show",$users["name"],$users['_id']) }}
</li>
@endforeach
</ul>
<div class="pf-users-branch__btn">
@can('create', App\Models\User::class)
{!! link_to_route("frontend.users.user.create",__('users.create'),[1,2,3],['class' => 'btn']) !!}
@endcan
</div>
</div>
</div>
</section>
@endsection
@section('footer')
@stop"#;

let expected_output = r#"@extends('frontend.layouts.app')
@section('title') foo
@endsection
@section('content')
<section id="content">
<div class="container mod-users-pd-h">
<div class="pf-user-header">
<div></div>
<p>@lang('users.index')</p>
</div>
<div class="pf-users-branch">
<ul class="pf-users-branch__list">
@foreach ($users as $user)
<li>
<img src="{{ asset('img/frontend/icon/branch-arrow.svg') }}" alt="branch_arrow">
{{ link_to_route('frontend.users.user.show', $users['name'], $users['_id']) }}
</li>
@endforeach
</ul>
<div class="pf-users-branch__btn">
@can('create', App\Models\User::class)
{!! link_to_route('frontend.users.user.create', __('users.create'), [1, 2, 3], ['class' => 'btn']) !!}
@endcan
</div>
</div>
</div>
</section>
@endsection
@section('footer')
@stop
"#;

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

let output = super::format_using_blade_formatter(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 @@ -8,6 +8,7 @@ use crate::{config::MdsfConfig, languages::Language};
pub mod autopep8;
pub mod biome;
pub mod black;
pub mod blade_formatter;
pub mod blue;
pub mod clang_format;
pub mod crystal_format;
Expand Down Expand Up @@ -96,6 +97,7 @@ pub fn format_snippet(config: &MdsfConfig, language: &Language, code: &str) -> S
let snippet_path = snippet.path();

if let Ok(Some(formatted_code)) = match language {
Language::Blade => config.blade.format(snippet_path),
Language::C => config.c.format(snippet_path),
Language::CSharp => config.csharp.format(snippet_path),
Language::Cpp => config.cpp.format(snippet_path),
Expand Down
154 changes: 154 additions & 0 deletions src/languages/blade.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
use schemars::JsonSchema;

use crate::formatters::{blade_formatter::format_using_blade_formatter, MdsfFormatter};

use super::{Lang, LanguageFormatter};

#[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub enum Blade {
#[default]
#[serde(rename = "blade-formatter")]
BladeFormatter,
}

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

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

impl LanguageFormatter for Blade {
#[inline]
fn format_snippet(
&self,
snippet_path: &std::path::Path,
) -> std::io::Result<(bool, Option<String>)> {
match self {
Self::BladeFormatter => format_using_blade_formatter(snippet_path),
}
}
}

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

use super::Blade;

const INPUT: &str = r#"@extends('frontend.layouts.app')
@section('title') foo
@endsection
@section('content')
<section id="content">
<div class="container mod-users-pd-h">
<div class="pf-user-header">
<div></div>
<p>@lang('users.index')</p>
</div>
<div class="pf-users-branch">
<ul class="pf-users-branch__list">
@foreach($users as $user)
<li>
<img src="{{ asset('img/frontend/icon/branch-arrow.svg') }}" alt="branch_arrow">
{{ link_to_route("frontend.users.user.show",$users["name"],$users['_id']) }}
</li>
@endforeach
</ul>
<div class="pf-users-branch__btn">
@can('create', App\Models\User::class)
{!! link_to_route("frontend.users.user.create",__('users.create'),[1,2,3],['class' => 'btn']) !!}
@endcan
</div>
</div>
</div>
</section>
@endsection
@section('footer')
@stop"#;

const EXTENSION: &str = crate::languages::Language::Blade.to_file_ext();

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

#[test]
fn it_should_not_format_when_enabled_is_false() {
let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file");
let snippet_path = snippet.path();

assert!(Lang::<Blade> {
enabled: false,
formatter: MdsfFormatter::Single(Blade::BladeFormatter),
}
.format(snippet_path)
.expect("it to not fail")
.is_none());
}

#[test]
fn test_blade_formatter() {
let expected_output = r#"@extends('frontend.layouts.app')
@section('title') foo
@endsection
@section('content')
<section id="content">
<div class="container mod-users-pd-h">
<div class="pf-user-header">
<div></div>
<p>@lang('users.index')</p>
</div>
<div class="pf-users-branch">
<ul class="pf-users-branch__list">
@foreach ($users as $user)
<li>
<img src="{{ asset('img/frontend/icon/branch-arrow.svg') }}" alt="branch_arrow">
{{ link_to_route('frontend.users.user.show', $users['name'], $users['_id']) }}
</li>
@endforeach
</ul>
<div class="pf-users-branch__btn">
@can('create', App\Models\User::class)
{!! link_to_route('frontend.users.user.create', __('users.create'), [1, 2, 3], ['class' => 'btn']) !!}
@endcan
</div>
</div>
</div>
</section>
@endsection
@section('footer')
@stop
"#;

let l = Lang::<Blade> {
enabled: true,
formatter: MdsfFormatter::Single(Blade::BladeFormatter),
};

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);
}
}
Loading

0 comments on commit 06a8fae

Please sign in to comment.