diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml
index f8087bd..260f5ef 100644
--- a/.github/workflows/validate.yml
+++ b/.github/workflows/validate.yml
@@ -62,6 +62,10 @@ jobs:
otp-version: "26"
gleam-version: "1.0.0"
elixir-version: "1.16.1"
+ # Used go shfmt
+ - uses: actions/setup-go@v5
+ with:
+ go-version: "stable"
- run: rustup toolchain install stable --profile minimal
- run: rustup component add rustfmt clippy
@@ -99,4 +103,10 @@ jobs:
- name: Install stylua
run: cargo install stylua
+ - name: Install shfmt
+ run: go install mvdan.cc/sh/v3/cmd/shfmt@latest
+
+ - name: Validate shfmt
+ run: shfmt --version
+
- run: cargo test
diff --git a/schemas/v0.0.0/mdsf.schema.json b/schemas/v0.0.0/mdsf.schema.json
index 5957806..19b61d9 100644
--- a/schemas/v0.0.0/mdsf.schema.json
+++ b/schemas/v0.0.0/mdsf.schema.json
@@ -3,6 +3,17 @@
"title": "MdsfConfig",
"type": "object",
"properties": {
+ "bash": {
+ "default": {
+ "enabled": true,
+ "formatter": "shfmt"
+ },
+ "allOf": [
+ {
+ "$ref": "#/definitions/Bash"
+ }
+ ]
+ },
"css": {
"default": {
"enabled": true,
@@ -170,6 +181,27 @@
}
},
"definitions": {
+ "Bash": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "default": true,
+ "type": "boolean"
+ },
+ "formatter": {
+ "default": "shfmt",
+ "allOf": [
+ {
+ "$ref": "#/definitions/BashFormatter"
+ }
+ ]
+ }
+ }
+ },
+ "BashFormatter": {
+ "type": "string",
+ "enum": ["shfmt"]
+ },
"Css": {
"type": "object",
"properties": {
diff --git a/src/config.rs b/src/config.rs
index 2025637..b62beab 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,8 +1,8 @@
use schemars::JsonSchema;
use crate::languages::{
- css::Css, elixir::Elixir, gleam::Gleam, html::Html, javascript::JavaScript, json::Json,
- lua::Lua, markdown::Markdown, nim::Nim, python::Python, rust::Rust, toml::Toml,
+ bash::Bash, css::Css, elixir::Elixir, gleam::Gleam, html::Html, javascript::JavaScript,
+ json::Json, lua::Lua, markdown::Markdown, nim::Nim, python::Python, rust::Rust, toml::Toml,
typescript::TypeScript, yaml::Yaml, zig::Zig,
};
@@ -12,6 +12,9 @@ pub struct MdsfConfig {
#[serde(rename = "$schema", default = "default_schema_location")]
pub schema: String,
+ #[serde(default)]
+ pub bash: Bash,
+
#[serde(default)]
pub css: Css,
@@ -63,6 +66,7 @@ impl Default for MdsfConfig {
fn default() -> Self {
Self {
schema: default_schema_location(),
+ bash: Bash::default(),
css: Css::default(),
elixir: Elixir::default(),
gleam: Gleam::default(),
diff --git a/src/formatters/mod.rs b/src/formatters/mod.rs
index 4190ef1..fd510ac 100644
--- a/src/formatters/mod.rs
+++ b/src/formatters/mod.rs
@@ -17,6 +17,7 @@ pub mod nimpretty;
pub mod prettier;
pub mod ruff;
pub mod rustfmt;
+pub mod shfmt;
pub mod stylua;
pub mod taplo;
pub mod zigfmt;
@@ -55,6 +56,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::Bash => config.bash.format(snippet_path),
Language::Css => config.css.format(snippet_path),
Language::Elixir => config.elixir.format(snippet_path),
Language::Gleam => config.gleam.format(snippet_path),
diff --git a/src/formatters/shfmt.rs b/src/formatters/shfmt.rs
new file mode 100644
index 0000000..c2b6635
--- /dev/null
+++ b/src/formatters/shfmt.rs
@@ -0,0 +1,93 @@
+use super::{execute_command, read_snippet};
+
+#[inline]
+pub fn format_using_shfmt(file_path: &std::path::Path) -> std::io::Result