summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrique Alves <henriquelalves@gmail.com>2022-07-06 02:13:29 -0300
committerHenrique Alves <henriquelalves@gmail.com>2022-07-25 12:04:15 -0300
commitb48e67262eb517f64cc67aedeafbe74f9fbbe690 (patch)
tree0811e25e52375a3926db703de9e92f7699d8c86b
downloadglam-b48e67262eb517f64cc67aedeafbe74f9fbbe690.tar.gz
glam-b48e67262eb517f64cc67aedeafbe74f9fbbe690.tar.bz2
glam-b48e67262eb517f64cc67aedeafbe74f9fbbe690.zip
first commit
-rw-r--r--.gitignore14
-rw-r--r--Cargo.toml10
-rw-r--r--src/content.rs32
-rw-r--r--src/main.rs249
-rw-r--r--src/utils.rs44
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();
+}