PRs welcome! 🎉
Adding support for a new build system is easy. Just 3 steps:
Create src/runners/your_runner.rs:
use crate::runner::{Command, Runner};
use std::path::Path;
pub struct YourRunner;
impl Runner for YourRunner {
fn name(&self) -> &'static str {
"your-tool" // e.g., "maven", "gradle", "cmake"
}
fn detect_files(&self) -> &'static [&'static str] {
&["your-config-file"] // e.g., &["pom.xml"], &["CMakeLists.txt"]
}
fn commands(&self, project_path: &Path) -> Vec<Command> {
vec![
Command::new("build", "your-cmd").with_args(vec!["build".into()]),
Command::new("test", "your-cmd").with_args(vec!["test".into()]),
// Add more commands...
]
}
}Add to src/runners/mod.rs:
mod your_runner;
pub use your_runner::YourRunner;
pub fn all_runners() -> Vec<Box<dyn Runner>> {
vec![
// ... existing runners
Box::new(YourRunner),
]
}Add your build system to README.md table:
| `your-config-file` | your-tool | build, test, ... |That's it!
pub trait Runner: Send + Sync {
/// Unique identifier (e.g., "cargo", "npm")
fn name(&self) -> &'static str;
/// Files that indicate this project type
fn detect_files(&self) -> &'static [&'static str];
/// Available commands for the project
fn commands(&self, project_path: &Path) -> Vec<Command>;
/// Execute a command (default impl usually works)
fn execute(&self, command: &Command, project_path: &Path) -> io::Result<ExitStatus>;
}// Simple command
Command::new("build", "make").with_args(vec!["build".into()])
// With description (shown in UI)
Command::new("dev", "npm")
.with_args(vec!["run".into(), "dev".into()])
.with_description("Start development server")- Dynamic commands: See
npm.rsfor parsing config files (package.json scripts) - Target extraction: See
make.rsfor parsing Makefile targets - Custom executables: See
make.rsfor reading custom commands from~/.frc
- Run
cargo fmtbefore committing - Run
cargo clippyand fix warnings - Keep it simple and minimal
Open an issue! We're happy to help.