It works!!

This commit is contained in:
Pagwin 2022-09-22 22:09:36 -04:00
parent ee5bec00e9
commit 002e5f3316
3 changed files with 89 additions and 64 deletions

51
Cargo.lock generated
View file

@ -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"

View file

@ -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"

View file

@ -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<String, Box<str>>,
skeletons:HashMap<String, String>,
// a hashmap of subcommands which can be created via running an external executable
scripts: HashMap<String,PathBuf>
}
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<std::io::Error> for Errors {
fn from(e: std::io::Error) -> Self {
Self::IoErr(e)
}
}
impl From<git2::Error> for Errors {
fn from(e: git2::Error) -> Self {
Self::GitErr(e)
}
}
impl From<CliError> 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::<String>(""){
match sub.get_one::<String>("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::<String>("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<std::io::Error> for CliError {
fn from(e: std::io::Error) -> Self {
Self::Io(e)
}
}
fn cli_fallback<S:AsRef<OsStr>, P:AsRef<Path>>(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(())
}
}