use std::{ env::{current_dir, var_os}, path::PathBuf, process, sync::mpsc::channel, }; use clap::Command; fn main() { let workspace_dir = var_os("CARGO_WORKSPACE_DIR") .map(PathBuf::from) .unwrap_or_else(|| current_dir().unwrap()); let matches = cli().get_matches(); match matches.subcommand() { Some(("backend", _)) => { process::Command::new("cargo") .arg("run") .arg("-p") .arg("backend") .current_dir(&workspace_dir) .stdout(process::Stdio::inherit()) .stderr(process::Stdio::inherit()) .status() .expect("running backend"); } Some(("entity", submatches)) => match submatches.subcommand() { Some(("generate", _)) => { process::Command::new("sea-orm-cli") .arg("generate") .arg("entity") .arg("-o") .arg("crates/entity/src/") .arg("--lib") .arg("--with-serde") .arg("both") .current_dir(&workspace_dir) .stdout(process::Stdio::inherit()) .stderr(process::Stdio::inherit()) .status() .expect("running entity generate"); } Some(("clean", _)) => { let dir = workspace_dir.join("crates/entity/src"); let files = dir.read_dir().expect("Failed to read entity directory"); for file in files { let file = file.expect("failed to get file path"); if file.file_name() == "lib.rs" { continue; } let file_path = file.path(); match std::fs::remove_file(&file_path) { Ok(_) => println!("Removed file {}", file_path.display()), Err(_) => println!("Failed to remove file {}", file_path.display()), } } } _ => { panic!( "Unknown command: entity {:?}", submatches.subcommand().map(|c| c.0) ) } }, Some(("frontend", submatches)) => match submatches.subcommand() { Some(("start", _)) => { let dir = workspace_dir.join("web"); let mut command = process::Command::new("pnpm") .arg("run") .arg("dev") .current_dir(dir) .stdout(process::Stdio::inherit()) .stderr(process::Stdio::inherit()) .spawn() .expect("running entity generate"); let (tx, rx) = channel(); ctrlc::set_handler(move || tx.send(()).expect("could not set signal")) .expect("failed setting ctrlc handler"); rx.recv().expect("could not recieve from channel"); command.kill().unwrap(); } _ => { panic!( "Unknown command: entity {:?}", submatches.subcommand().map(|c| c.0) ) } }, _ => { panic!("Unknown command: {:?}", matches.subcommand().map(|c| c.0)) } } } fn cli() -> Command { Command::new("xtask") .about("docusphere useful commands") .subcommand_required(true) .subcommand(Command::new("backend")) .subcommand( Command::new("entity") .subcommand_required(true) .subcommand(Command::new("generate")) .subcommand(Command::new("clean")), ) .subcommand( Command::new("frontend") .subcommand_required(true) .subcommand(Command::new("start")), ) }