diff --git a/Cargo.lock b/Cargo.lock index cfccb3c..3b4db43 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,15 +25,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bstr" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" -dependencies = [ - "memchr", -] - [[package]] name = "cc" version = "1.0.73" @@ -248,21 +239,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", -] - [[package]] name = "once_cell" version = "1.14.0" @@ -308,12 +284,11 @@ checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" [[package]] name = "ppi" -version = "0.1.0" +version = "1.0.0" dependencies = [ "clap", "dirs", "git2", - "rlua", "serde", "toml", ] @@ -380,30 +355,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "rlua" -version = "0.19.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b38117a836316ef62c02f6751e6d28e2eb53a1c35f0329427a9fb9c1c7b6a0" -dependencies = [ - "bitflags", - "bstr", - "libc", - "num-traits", - "rlua-lua54-sys", -] - -[[package]] -name = "rlua-lua54-sys" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ae48797c3e76fb2c205fda8f30e28416a15b9fc1d649cc7cea9ff1fb9cf028" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - [[package]] name = "serde" version = "1.0.144" diff --git a/Cargo.toml b/Cargo.toml index bcda6f1..dfee31b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ppi" -version = "0.1.0" +version = "1.0.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -9,6 +9,5 @@ edition = "2021" clap = { version = "3.2.22", features = ["derive", "cargo"] } dirs = "4.0.0" git2 = "0.15.0" -rlua = "0.19.4" serde = { version = "1.0.144", features = ["derive"] } toml = "0.5.9" diff --git a/src/main.rs b/src/main.rs index 81e147a..da83711 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,23 +1,47 @@ -extern crate rlua; extern crate clap; extern crate serde; extern crate toml; extern crate git2; -use std::{path::{Path, PathBuf}, io::Read, collections::{HashMap, HashSet}}; +use std::{path::{PathBuf, Path}, io::{Read, Cursor}, collections::{HashMap, HashSet}, ffi::OsStr}; -use clap::{Command, AppSettings, Arg}; +use clap::{Command, Arg}; use serde::{Serialize, Deserialize}; + #[derive(Serialize, Deserialize,Default)] -struct Config{ +struct Subcommands{ //a hashmap of subcommands which can be created via cloning a skeleton repository - skeletons:HashMap>, + skeletons:HashMap, // a hashmap of subcommands which can be created via running an external executable scripts: HashMap } -pub fn main() { - // +#[derive(Serialize, Deserialize,Default)] +struct Config{ + subcommands: Subcommands +} + + +#[derive(Debug)] +enum Errors{IoErr(std::io::Error), GitErr(git2::Error), CliErr(CliError), Unknown} +impl From for Errors { + fn from(e: std::io::Error) -> Self { + Self::IoErr(e) + } +} +impl From for Errors { + fn from(e: git2::Error) -> Self { + Self::GitErr(e) + } +} +impl From for Errors{ + fn from(e: CliError) -> Self{ + Self::CliErr(e) + } +} + +fn main() -> Result<(),Errors> { + let config:Config = toml::from_str({ let mut buf = String::new(); let _ = std::fs::File::open( @@ -28,7 +52,7 @@ pub fn main() { buf }.as_str()).unwrap_or_default(); - let Config {scripts,skeletons} = config; + let Config {subcommands:Subcommands { skeletons, scripts }} = config; // Making sure the skeletons and scripts don't have overlap that will cause issue later { @@ -39,16 +63,39 @@ pub fn main() { } } - let mut program = Command::new("project-init") - .subcommands(skeletons.keys().map(|v|Command::new(v).arg(Arg::new("output_dir").takes_value(true)))) + let mut program = Command::new(clap::crate_name!()) + .version(clap::crate_version!()) + .author(clap::crate_authors!()) + .subcommands(skeletons.keys().map(|v|Command::new(v).arg(Arg::new("output_dir").takes_value(true).action(clap::ArgAction::Append)))) .subcommands(scripts.keys().map(|v|Command::new(v).arg(Arg::new("script_args").takes_value(true)))); + let mut short_help = String::new(); + let mut long_help = String::new(); + { + let mut short_help_buf = Vec::new(); + let mut long_help_buf = Vec::new(); + program.write_help(&mut Cursor::new(&mut short_help_buf))?; + program.write_help(&mut Cursor::new(&mut long_help_buf))?; + short_help_buf.as_slice().read_to_string(&mut short_help)?; + long_help_buf.as_slice().read_to_string(&mut long_help)?; + } program.build(); let matches = program.get_matches(); for skelly in skeletons { if let Some(sub) = matches.subcommand_matches(skelly.0){ - match sub.get_one::(""){ + match sub.get_one::("output_dir"){ Some(loc)=>{ - + let repo = match git2::Repository::clone(skelly.1.as_ref(), loc){ + Ok(repo)=>{ + repo + } + Err(_)=>{ + eprintln!("libgit2 failed clone falling back to cli"); + cli_fallback(skelly.1,loc)?; + git2::Repository::open(loc)? + } + }; + repo.remote_delete("origin")?; + return Ok(()) } None=>{ println!("failed to provide a path to clone the skeleton directory into"); @@ -57,4 +104,32 @@ pub fn main() { } } } + for script in scripts { + if let Some(sub) = matches.subcommand_matches(script.0){ + std::process::exit(std::process::Command::new(script.1).args(sub.get_many::("script_args").map(Iterator::collect).unwrap_or(Vec::new())).spawn()?.wait()?.code().ok_or(Errors::Unknown)?); + } + } + println!("{}", short_help); + Ok(()) +} +#[derive(Debug)] +enum CliError{Io(std::io::Error), NonZero} +impl From for CliError { + fn from(e: std::io::Error) -> Self { + Self::Io(e) + } +} +fn cli_fallback, P:AsRef>(source:S, dest: P)->Result<(),CliError>{ + + let mut child = std::process::Command::new("git"); + child + .arg("clone") + .arg(source) + .arg(dest.as_ref()); + if !child.spawn()?.wait()?.success() { + Err(CliError::NonZero) + } + else{ + Ok(()) + } }