use std::env::set_current_dir; use std::fs; use std::io::Write as _; use std::process::Command; use structopt::StructOpt; const TOSIN_DEPENDENCY: &str = concat!(r#"tosin = { path = ""#, env!("CARGO_MANIFEST_DIR"), r#"" }"#); const PROJECT_MAIN: &str = r#" use tosin::Settings; use tosin::contrib::admin; use tosin::urls::{UrlMap, url_map}; fn urls() -> UrlMap { url_map! { "admin" / ..admin::site::urls(), } } fn settings() -> Settings { Settings { ..Settings::default() } } tosin::main!(urls(), settings()); "#; #[derive(StructOpt, Debug)] enum Opt { /// Start a new project/site (can contain multiple apps) StartProject { name: Option, } } fn main() { let opts = Opt::from_args(); match opts { Opt::StartProject { name } => { match name { Some(name) => { // there's a name, so we're creating a project. // TODO make this all more robust let cargo_new = Command::new("cargo") .args(&["new", "--bin", &name]) .status() .unwrap(); if !cargo_new.success() { panic!("cargo new failed"); } set_current_dir(name).unwrap(); let mut cargo_toml = fs::OpenOptions::new() .append(true) .open("Cargo.toml") .unwrap(); writeln!(cargo_toml, "{}", TOSIN_DEPENDENCY).unwrap(); drop(cargo_toml); fs::write("src/main.rs", PROJECT_MAIN).unwrap(); } None => { todo!("absorb existing Rust project maybe??") } } } } }