diff options
author | Henrique Alves <henriquelalves@gmail.com> | 2022-07-06 02:13:29 -0300 |
---|---|---|
committer | Henrique Alves <henriquelalves@gmail.com> | 2022-07-25 12:04:15 -0300 |
commit | b48e67262eb517f64cc67aedeafbe74f9fbbe690 (patch) | |
tree | 0811e25e52375a3926db703de9e92f7699d8c86b | |
download | glam-b48e67262eb517f64cc67aedeafbe74f9fbbe690.tar.gz glam-b48e67262eb517f64cc67aedeafbe74f9fbbe690.tar.bz2 glam-b48e67262eb517f64cc67aedeafbe74f9fbbe690.zip |
first commit
-rw-r--r-- | .gitignore | 14 | ||||
-rw-r--r-- | Cargo.toml | 10 | ||||
-rw-r--r-- | src/content.rs | 32 | ||||
-rw-r--r-- | src/main.rs | 249 | ||||
-rw-r--r-- | src/utils.rs | 44 |
5 files changed, 349 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ada8be9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb
\ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..3459ef1 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "glam" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +clap = { version = "3.0", features = ["derive"] } +json = "0.12.4"
\ No newline at end of file diff --git a/src/content.rs b/src/content.rs new file mode 100644 index 0000000..9c11dd6 --- /dev/null +++ b/src/content.rs @@ -0,0 +1,32 @@ +pub fn create_gitignore_file() -> String { + return +r#"# Godot-specific ignores +.import/ +export.cfg +export_presets.cfg + +# Imported translations (automatically generated from CSV files) +*.translation + +# Mono-specific ignores +.mono/ +data_*/ + +# Glam-specific ignores +.glam.d/"#.to_string(); +} + +pub fn create_gdignore_file() -> String { + return +r#"# Glam-specific ignores +.glam.d/"#.to_string(); +} + +pub fn create_glam_file() -> String { + return +r#"{ + "packages" : { + } +} +"#.to_string(); +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..8e4e225 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,249 @@ +use clap::{Parser, Subcommand}; +use std::path::{Path, PathBuf}; +use std::fs::write; +use std::process::exit; +use std::fs; +use json; + +mod content; +mod utils; + +#[derive(Parser)] +struct Cli { + #[clap(subcommand)] + command: Commands, +} + +#[derive(Subcommand)] +enum Commands { + Init { + }, + + /// Install new addon + Install { + /// Addon project git + git_repo: String + }, + + Update { + }, + + Remove { + }, +} + +#[derive(Clone)] +#[derive(Debug)] +struct GlamObject { + name : String, + git_repo : String +} + +fn main() { + let cli = Cli::parse(); + + match &cli.command { + Commands::Init {} => { + initialize(); + }, + + Commands::Install {git_repo: git_address} => { + check_initialization(); + install_addon(git_address); + }, + + Commands::Update {} => { + check_initialization(); + update_addon(); + }, + + Commands::Remove {} => { + check_initialization(); + remove_addon(); + }, + } +} + +fn initialize() { + if !Path::new("./.gitignore").exists() { + match write("./.gitignore", content::create_gitignore_file()) { + Ok(_v) => (), + Err(_e) => { + println!("There was a problem creating the .gitignore file!"); + exit(1); + } + } + } + + if !Path::new("./.gdignore").exists() { + match write("./.gdignore", content::create_gdignore_file()) { + Ok(_v) => (), + Err(_e) => { + println!("There was a problem creating the .gdignore file!"); + exit(1); + } + } + } +} + +fn check_initialization() { + if !Path::new("./.gitignore").exists() { + println!(".gitignore file does not exist!"); + } + if !Path::new("./.gdignore").exists() { + println!(".gdignore file does not exist!"); + } +} + +fn install_addon(git_repo : &str) { + + // Search for project root folder + let root = search_project_root(); + println!("Found root project in: {}", root); + + // Create glam.d/ folder if it doesn't exist + if !Path::new(&format!("{}/.glam.d/", root)).exists() { + utils::run_shell_command( + &format!("mkdir -p {}/.glam.d/", root), + None + ); + } + + // Create .glam file if it doesn't exist + if !Path::new(&format!("{}/.glam", root)).exists() { + fs::write(&format!("{}/.glam",root), + content::create_glam_file()) + .expect("Couldn't create .glam file!"); + } + + // Find glam object or create one with default configuration + let mut glam_objects = read_glam_file(); + let mut glam_obj : Option<GlamObject> = None; + let name = utils::get_repo_name(git_repo); + + for obj in glam_objects.iter() { + if obj.name == name { + glam_obj = Some(obj.clone()); + } + } + + match glam_obj { + None => { + let obj = GlamObject{ + git_repo : git_repo.to_string(), + name : name.to_string() + }; + + glam_obj = Some(obj.clone()); + glam_objects.push(obj); + } + + _ => {} + } + + let target_obj = glam_obj.unwrap(); + + // If glam addon folder doesn't exist, clone project + if !Path::new(&format!("{}/.glam.d/{}", root, target_obj.name)).exists() { + utils::run_shell_command( + &format!("cd {}/.glam.d/ && git clone {} {}", root, target_obj.git_repo, target_obj.name), + None + ); + println!("Created addon folder on .glam.d!"); + } else { + println!("Not Created!"); + } + + // If project addon folder doesn't exist, create it + utils::run_shell_command( + &format!("mkdir -p {}/addons/{}", root, name), + None + ); + + // TODO: use source_folder to copy files from (default: /addons/) + // TODO: use target_folder to copy files to (defautl: (root)/) + // Copy addon repository content to target folder + utils::run_shell_command( + &format!("cp -f -r {}/.glam.d/{}/addons/* -t {}/addons/",root, name, root), + None + ); + + // Write .glam file + write_glam_file(&glam_objects); +} + +// TODO: Use root folder +fn read_glam_file() -> Vec<GlamObject> { + if !Path::new("./.glam").exists() { + fs::write("./.glam", content::create_glam_file()).expect("Couldn't create .glam file!"); + } + + let glam_content = fs::read_to_string("./.glam").expect("Couldn't read .glam file!"); + let glam_obj = json::parse(&glam_content).expect("Couldn't parse .glam file!"); + + let packages = &glam_obj["packages"]; + + let mut glam_objects = Vec::new(); + + println!("{}", packages); + for i in packages.entries() { + println!("{}", i.1); + glam_objects.push( + GlamObject{ + name : i.1["name"].to_string(), + git_repo : i.1["git_repo"].to_string() + } + ); + } + + return glam_objects; +} + +// TODO: Use root folder +fn write_glam_file(glam_objects : &Vec<GlamObject>) { + let mut data = json::object!{}; + data["packages"] = json::object!{}; + + for glam_obj in glam_objects { + println!("{:?}", glam_obj); + data["packages"][&glam_obj.name] = json::object!{}; + data["packages"][&glam_obj.name]["name"] = glam_obj.clone().name.into(); + data["packages"][&glam_obj.name]["git_repo"] = glam_obj.clone().git_repo.into(); + } + + let json_string = json::stringify(data); + + println!("{}", json_string); + fs::write("./.glam", json_string).expect("Couldn't create .glam file!"); +} + +fn update_addon() { +} + +fn remove_addon() { +} + +fn search_project_root() -> String{ + let path = PathBuf::from("./"); + let mut dir = path.canonicalize().unwrap(); + + loop { + let dir_path = dir.to_str().unwrap(); + let proj_path = format!("{}/project.godot", dir_path); + println!("{}", proj_path); + let godot_project = Path::new(&proj_path); + + if godot_project.exists() { + break; + } + else { + let parent = dir.parent(); + if parent.is_none() { + panic!("Godot project not found!"); + } + dir = dir.parent().unwrap().to_path_buf(); + } + } + + return dir.to_str().unwrap().to_string(); +} diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..271cf6d --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,44 @@ +pub fn get_repo_name(repo: &str) -> String { + let mut chars = repo.chars().rev(); + let length = repo.chars().count(); + let mut last_i = 0; + let mut first_i = 0; + + let mut i = length; + println!("{}", i); + + while i > 0 { + match chars.next() { + Some('.') => { + last_i = i-1; + } + Some('/') => { + first_i = i; + break; + } + _ => {} + } + i -= 1; + } + + if last_i == 0 { + last_i = length; + } + + println!("{} {}", first_i, last_i); + let name = &repo[first_i..last_i]; + println!("{}", name); + // TODO: Return a Result (may be error) + return name.to_string(); +} + +pub fn run_shell_command(command : &str, folder : Option<&str>) -> bool { + let status = std::process::Command:: + new("sh") + .current_dir(folder.unwrap_or("./")) + .arg("-c") + .arg(command) + .status() + .expect("Error running command."); + return status.success(); +} |