gsa 0.2.1

Game development library modelled after an imaginary console
Documentation
use clap::{crate_name, crate_version, Parser, Subcommand};
use dunce::canonicalize;
use path_slash::PathExt;
use std::fs;
use std::fs::{write, OpenOptions};
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::{exit, Command};

#[derive(Parser)]
struct Cli {
    #[command(subcommand)]
    command: Cmd,
}

#[derive(Subcommand)]
enum Cmd {
    /// Creates a new GSA project
    New {
        /// Name of new project
        name: String,
        /// Use local path to GSA instead of crates.io
        #[arg(long, short)]
        local: Option<PathBuf>,
        /// Overwrite dir/file with name? WARNING: will delete stuff without further confirmation
        #[arg(long)]
        overwrite: bool,
    },
}

fn main() {
    let cli = Cli::parse();

    match cli.command {
        Cmd::New {
            name,
            local,
            overwrite,
        } => {
            println!("creating {}", name);
            let path = Path::new(&name);
            if path.exists() {
                if overwrite {
                    if path.is_dir() {
                        fs::remove_dir_all(path).unwrap();
                    } else {
                        fs::remove_file(path).unwrap();
                    }
                } else {
                    eprintln!(
                        "aborting: file or directory {} already exists; use --overwrite if you want to delete it",
                        name
                    );
                    exit(1);
                }
            }
            if !Command::new("cargo")
                .arg("new")
                .arg(&name)
                .status()
                .unwrap()
                .success()
            {
                eprintln!("aborting: cargo new failed");
                exit(1);
            }
            let mut cargo = OpenOptions::new()
                .write(true)
                .append(true)
                .open(path.join("Cargo.toml"))
                .expect("opening Cargo.toml failed");
            match local {
                None => {
                    writeln!(cargo, "{} = \"{}\"", crate_name!(), crate_version!()).unwrap();
                }
                Some(local) => {
                    writeln!(
                        cargo,
                        "{} = {{path = \"{}\"}}\n",
                        crate_name!(),
                        canonicalize(local)
                            .expect("couldn't find path")
                            .to_slash_lossy(),
                    )
                    .unwrap();
                }
            }
            writeln!(
                cargo,
                "glam = \"0.24.0\"\n\n[profile.dev.package.{}]\nopt-level = 3",
                crate_name!()
            )
            .unwrap();
            write(
                path.join("src/main.rs"),
                include_str!("../examples/hello_world/main.rs"),
            )
            .unwrap();
            write(
                path.join("src/gfx.gif"),
                include_bytes!("../examples/hello_world/gfx.gif"),
            )
            .unwrap();
        }
    }
}