From 9b60e6092a3e64a21a9acfe338483a7347ad88ce Mon Sep 17 00:00:00 2001 From: godsfryingpan Date: Mon, 23 Mar 2026 17:17:35 -0500 Subject: [PATCH 1/4] Add format and linting --- PKGBUILD | 2 +- src/app.rs | 88 ++++++++++++++++++++++++++++++++++++- src/templates/.clang-format | 23 ++++++++++ src/templates/.clang-tidy | 2 + src/templates/.gitignore | 2 + 5 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 src/templates/.clang-format create mode 100644 src/templates/.clang-tidy create mode 100644 src/templates/.gitignore diff --git a/PKGBUILD b/PKGBUILD index b89bc34..706f278 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -6,7 +6,7 @@ pkgdesc="A simple C project manager inspired by Cargo" arch=('x86_64') url="" license=('MIT') -depends=('gcc' 'pkgconf') +depends=('gcc' 'pkgconf' 'clang') makedepends=('rust' 'cargo') source=() diff --git a/src/app.rs b/src/app.rs index d1a3f2f..4496e02 100644 --- a/src/app.rs +++ b/src/app.rs @@ -10,7 +10,9 @@ use colored::Colorize; use glob::glob; const MAIN_C: &str = include_str!("templates/main.c"); -const GITIGNORE: &str = "target/\ncompile_commands.json\n"; +const GITIGNORE: &str = include_str!("templates/.gitignore"); +const CLANG_FORMAT: &str = include_str!("templates/.clang-format"); +const CLANG_TIDY: &str = include_str!("templates/.clang-tidy"); #[derive(clap::Parser)] #[clap(version, about)] @@ -74,6 +76,8 @@ enum Subcommand { /// The package to remove package: String, }, + Fmt, + Lint, } #[derive(clap::Subcommand)] @@ -212,6 +216,18 @@ impl App { std::process::exit(1); } } + Subcommand::Fmt => { + if let Err(e) = fmt() { + eprintln!("Error formatting project: {e}"); + std::process::exit(1); + } + } + Subcommand::Lint => { + if let Err(e) = lint() { + eprintln!("Error linting project: {e}"); + std::process::exit(1); + } + } } } } @@ -542,6 +558,8 @@ fn create_project>(directory: P) -> std::io::Result<()> { std::fs::write("src/main.c", MAIN_C)?; std::fs::write(".gitignore", GITIGNORE)?; + std::fs::write(".clang-tidy", CLANG_TIDY)?; + std::fs::write(".clang-format", CLANG_FORMAT)?; let lossy = pathdir.to_string_lossy(); @@ -792,3 +810,71 @@ fn clean() -> std::io::Result<()> { Ok(()) } + +fn fmt() -> std::io::Result<()> { + let source_files: Vec = glob("src/*.c") + .map_err(|e| std::io::Error::new(std::io::ErrorKind::NotFound, format!("{e}")))? + .chain( + glob("src/*.h") + .map_err(|e| std::io::Error::new(std::io::ErrorKind::NotFound, format!("{e}")))?, + ) + .filter_map(|e| e.ok()) + .collect(); + + let status = Command::new("clang-format") + .arg("-i") + .args(&source_files) + .status() + .map_err(|_| { + std::io::Error::new( + std::io::ErrorKind::NotFound, + "clang-format not found — try installing it (e.g. sudo pacman -S clang)", + ) + })?; + + if !status.success() { + return Err(std::io::Error::other("clang-format failed")); + } + + println!(" {} all source files", "Formatted".green().bold()); + + Ok(()) +} + +fn lint() -> std::io::Result<()> { + gen_compile_commands(&None)?; + + let source_files: Vec = glob("src/*.c") + .map_err(|e| std::io::Error::new(std::io::ErrorKind::NotFound, format!("{e}")))? + .filter_map(|e| e.ok()) + .collect(); + + let mut any_warnings = false; + + for src in &source_files { + println!(" {} {}", "Linting".green().bold(), src.display()); + + let status = Command::new("clang-tidy") + .arg(src) + .arg("--use-color") + .status() + .map_err(|_| { + std::io::Error::new( + std::io::ErrorKind::NotFound, + "clang-tidy not found — try installing it (e.g. sudo pacman -S clang)", + ) + })?; + + if !status.success() { + any_warnings = true; + } + } + + if any_warnings { + println!("\n {} lint warnings found", "Warning".yellow().bold()); + } else { + println!("\n {} no issues found", "Finished".green().bold()); + } + + Ok(()) +} diff --git a/src/templates/.clang-format b/src/templates/.clang-format new file mode 100644 index 0000000..a614e9b --- /dev/null +++ b/src/templates/.clang-format @@ -0,0 +1,23 @@ +BasedOnStyle: LLVM +IndentWidth: 4 +TabWidth: 4 +UseTab: Never +ColumnLimit: 100 + +BreakBeforeBraces: Attach +BraceWrapping: + AfterFunction: false + AfterControlStatement: false + +SpaceAfterCStyleCast: false +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesInCStyleCastParentheses: false + +AlignConsecutiveAssignments: Consecutive +AlignConsecutiveDeclarations: Consecutive + +PointerAlignment: Right + +SortIncludes: CaseSensitive +IncludeBlocks: Regroup diff --git a/src/templates/.clang-tidy b/src/templates/.clang-tidy new file mode 100644 index 0000000..a7a8b2b --- /dev/null +++ b/src/templates/.clang-tidy @@ -0,0 +1,2 @@ +Checks: "clang-diagnostic-*,clang-analyzer-*" +WarningsAsErrors: "" diff --git a/src/templates/.gitignore b/src/templates/.gitignore new file mode 100644 index 0000000..18dd0cd --- /dev/null +++ b/src/templates/.gitignore @@ -0,0 +1,2 @@ +target/ +compile_commands.json \ No newline at end of file -- 2.49.1 From bbaaf818b2c97c90da872aeb512fa395c7917b15 Mon Sep 17 00:00:00 2001 From: godsfryingpan Date: Mon, 23 Mar 2026 17:18:32 -0500 Subject: [PATCH 2/4] update main.c to use formatting --- src/templates/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/templates/main.c b/src/templates/main.c index 1089a12..3bccb6c 100644 --- a/src/templates/main.c +++ b/src/templates/main.c @@ -1,7 +1,7 @@ #include int main() { - printf("Hello, world!\n"); + printf("Hello, world!\n"); - return 0; + return 0; } -- 2.49.1 From 5b9409bec2298c9af8169ab717254e19d02b14e5 Mon Sep 17 00:00:00 2001 From: godsfryingpan Date: Mon, 23 Mar 2026 17:29:43 -0500 Subject: [PATCH 3/4] Add descriptions for fmt and lint --- src/app.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app.rs b/src/app.rs index 4496e02..b820373 100644 --- a/src/app.rs +++ b/src/app.rs @@ -76,7 +76,9 @@ enum Subcommand { /// The package to remove package: String, }, + /// Format C source code using clang-format Fmt, + /// Lint C source code using clang-tidy Lint, } -- 2.49.1 From ccc6d2a4970dbf476831ae6be1057bc1520a556d Mon Sep 17 00:00:00 2001 From: godsfryingpan Date: Mon, 23 Mar 2026 17:30:35 -0500 Subject: [PATCH 4/4] change output a little bit for formatting --- src/app.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app.rs b/src/app.rs index b820373..c6f7c4f 100644 --- a/src/app.rs +++ b/src/app.rs @@ -854,7 +854,7 @@ fn lint() -> std::io::Result<()> { let mut any_warnings = false; for src in &source_files { - println!(" {} {}", "Linting".green().bold(), src.display()); + println!(" {} {}", "Linting".green().bold(), src.display()); let status = Command::new("clang-tidy") .arg(src) @@ -873,9 +873,9 @@ fn lint() -> std::io::Result<()> { } if any_warnings { - println!("\n {} lint warnings found", "Warning".yellow().bold()); + println!("\n {} lint warnings found", "Warning".yellow().bold()); } else { - println!("\n {} no issues found", "Finished".green().bold()); + println!("\n {} no issues found", "Finished".green().bold()); } Ok(()) -- 2.49.1