From 2f1834bb0d9cc97bb84f1cd1062154943fd7100a Mon Sep 17 00:00:00 2001 From: Diana Date: Sat, 4 Nov 2023 22:06:06 -0700 Subject: [PATCH] Starting project refactoring - version 0.2.0 --- .gitignore | 4 + Cargo.toml | 4 +- src/controller/down/mod.rs | 0 src/controller/init/mod.rs | 77 ------- src/controller/init/submodules/mod.rs | 123 ----------- src/controller/mod.rs | 193 ------------------ src/controller/new/mod.rs | 0 src/controller/setup/mod.rs | 0 src/controller/up/mod.rs | 0 src/controller/watch/mod.rs | 0 src/helpers/config/app_config/mod.rs | 133 ------------ src/helpers/config/mod.rs | 1 - src/helpers/docker/docker_compose/file.rs | 53 ----- src/helpers/docker/docker_compose/mod.rs | 5 - src/helpers/docker/mod.rs | 1 - src/helpers/filesystem/dir.rs | 116 ----------- src/helpers/filesystem/file.rs | 35 ---- src/helpers/filesystem/mod.rs | 3 - src/helpers/filesystem/path.rs | 25 --- src/helpers/git/mod.rs | 0 src/helpers/help/init_help.rs | 17 -- src/helpers/help/main_help.rs | 25 --- src/helpers/help/mod.rs | 23 --- src/helpers/mod.rs | 7 - src/helpers/program_checker/mod.rs | 0 src/helpers/user_input/mod.rs | 164 --------------- src/main.rs | 9 +- src/models/app_config/mod.rs | 2 +- src/models/docker_compose/mod.rs | 5 +- src/models/project/mod.rs | 5 +- src/models/repository/mod.rs | 11 +- src/test/main.rs | 1 - .../models/app_config/config.yaml | 0 src/{test => tests}/models/docker | 0 .../models/docker_compose/docker-compose.yaml | 0 .../models/project/project.yaml | 0 .../models/repository/example_api_call.json | 0 37 files changed, 23 insertions(+), 1019 deletions(-) delete mode 100644 src/controller/down/mod.rs delete mode 100644 src/controller/init/mod.rs delete mode 100644 src/controller/init/submodules/mod.rs delete mode 100644 src/controller/mod.rs delete mode 100644 src/controller/new/mod.rs delete mode 100644 src/controller/setup/mod.rs delete mode 100644 src/controller/up/mod.rs delete mode 100644 src/controller/watch/mod.rs delete mode 100644 src/helpers/config/app_config/mod.rs delete mode 100644 src/helpers/config/mod.rs delete mode 100644 src/helpers/docker/docker_compose/file.rs delete mode 100644 src/helpers/docker/docker_compose/mod.rs delete mode 100644 src/helpers/docker/mod.rs delete mode 100644 src/helpers/filesystem/dir.rs delete mode 100644 src/helpers/filesystem/file.rs delete mode 100644 src/helpers/filesystem/mod.rs delete mode 100644 src/helpers/filesystem/path.rs delete mode 100644 src/helpers/git/mod.rs delete mode 100644 src/helpers/help/init_help.rs delete mode 100644 src/helpers/help/main_help.rs delete mode 100644 src/helpers/help/mod.rs delete mode 100644 src/helpers/mod.rs delete mode 100644 src/helpers/program_checker/mod.rs delete mode 100644 src/helpers/user_input/mod.rs delete mode 100644 src/test/main.rs rename src/{test => tests}/models/app_config/config.yaml (100%) rename src/{test => tests}/models/docker (100%) rename src/{test => tests}/models/docker_compose/docker-compose.yaml (100%) rename src/{test => tests}/models/project/project.yaml (100%) rename src/{test => tests}/models/repository/example_api_call.json (100%) diff --git a/.gitignore b/.gitignore index 5892940..49c7279 100644 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,8 @@ Cargo.lock # self-testing folder testing/ +# submodules .gitmodules + +# OS generated files +.DS_Store \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 3ae44ad..1f3b9af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tools" -version = "0.1.0" +version = "0.2.0" edition = "2021" authors = ["Diana Moore "] description = "A collection of tools for the terminal." @@ -13,7 +13,7 @@ readme = "README.md" [dependencies] crossterm = "0.27.0" once_cell = "1.18.0" -ratatui = "0.24.0" +ratatui = { version = "0.24.0", features = ["all-widgets"] } semver = "1.0.20" serde = { version = "1.0.189", features = ["derive"] } serde_json = "1.0.107" diff --git a/src/controller/down/mod.rs b/src/controller/down/mod.rs deleted file mode 100644 index e69de29..0000000 diff --git a/src/controller/init/mod.rs b/src/controller/init/mod.rs deleted file mode 100644 index a605c72..0000000 --- a/src/controller/init/mod.rs +++ /dev/null @@ -1,77 +0,0 @@ -// Module: controller::init -mod submodules; -use self::submodules::delete_all_submodules; -use crate::helpers::user_input; -use submodules::{check_if_submodule_init_run_needed, get_submodule_paths}; - -/// ## rebuilt() -/// This function deletes all the items created by `init()` and then -/// reinitializes the project and creates the necessary files and -/// directories for the project. -/// -/// ### returns: () -pub fn rebuild_full(args: &[String]) { - if args.get(0).map(|s| s.as_str()) == Some("-y") { - clean_logic(); - } else { - println!("Cleaning the project... Are you sure you want to do this?"); - println!("This will delete all the files and directories created by the init command."); - - if user_input::get_user_input_with_options("Continue? [y/N]: ", &["y"]) { - println!("Cleaning the project..."); - clean_logic(); - } else { - println!("Aborting..."); - } - } - - // init the project - init(); -} - -/// ## clean_logic() -/// this function contains the logic for the clean command and -/// deletes all the items created by `init()` leaving the -/// project in a uninitialized state. -/// -/// ### returns: () -fn clean_logic() { - println!("Cleaning the project..."); - - // delete all submodules - delete_all_submodules(); -} - -/// ## clean() -/// This function -/// -/// ### returns: () -pub fn clean(args: &[String]) { - // check if the -y flag was passed to the command - // if it was not, ask the user for confirmation - if args.get(0).map(|s| s.as_str()) == Some("-y") { - clean_logic(); - } else { - println!("Cleaning the project... Are you sure you want to do this?"); - println!("This will delete all the files and directories created by the init command."); - - if user_input::get_user_input_with_options("Continue? [y/N]: ", &["y"]) { - println!("Cleaning the project..."); - - // delete all submodules - delete_all_submodules(); - } else { - println!("Aborting..."); - } - } -} - -/// ## init() -/// This function initializes the project and creates the necessary -/// files and directories for the project. -/// -/// ### returns: () -pub fn init() { - // check if all submodules have been initialized - check_if_submodule_init_run_needed(get_submodule_paths()); -} diff --git a/src/controller/init/submodules/mod.rs b/src/controller/init/submodules/mod.rs deleted file mode 100644 index 28335b7..0000000 --- a/src/controller/init/submodules/mod.rs +++ /dev/null @@ -1,123 +0,0 @@ -use crate::helpers::filesystem::dir::map_dirs; -use crate::CONFIG; - -// ## get_submodule_paths() -> Vec<(String, String, bool)> -// This function reads the .gitmodules file and returns the paths of the submodules -// -// ### arguments: -// - nothing -// -// ### returns: -// - Vec<(String, String, bool)> - vector of tuples containing information about the submodules -// - (String, String, bool) - (submodule name, submodule path, submodule initialized) -pub fn get_submodule_paths() -> Vec<(String, String, bool)> { - // read the config file and get the .gitmodules file path and root path - let base_path = CONFIG.project_path.clone(); - // try to get the path to .gitmodule file in the current directory - let submodule_path = std::fs::canonicalize(format!("{}/{}", base_path, ".gitmodules")) - .expect("Couldn't get path to .gitmodules file") - .to_str() - .unwrap() - .to_string(); - - // read the .gitmodules file and get the paths of the submodules - // example .gitmodules file: - // [submodule "backend"] - // path = backend - // url = git@github.com:xN4P4LM-org/{project} - let sub_module_paths = std::fs::read_to_string(format!("{}/{}", base_path, submodule_path)) - .expect("Couldn't read .gitmodules file") - .lines() - .filter(|line| line.contains("path = ")) - .map(|line| line.replace("path = ", "").trim().to_string()) - .collect::>(); - - // return the submodule paths - map_dirs(sub_module_paths) -} - -// check_if_submodule_init_run_needed(sub_module_paths: Vec<(String, String, bool)>) -// This function checks if the submodules are initialized and if not, -// it runs the command `git submodule update --init --recursive` in the project directory -// -// ### arguments: -// - sub_module_paths: Vec<(String, String, bool)> - vector of tuples containing information about the submodules -// - (String, String, bool) - (submodule name, submodule path, submodule initialized) -// -// ### returns: -// - nothing -pub fn check_if_submodule_init_run_needed(sub_module_paths: Vec<(String, String, bool)>) -> bool { - let mut missing_submodule = false; - - for dir in sub_module_paths { - println!("{} - {} - {}", &dir.0, &dir.1, &dir.2); - - // if the directory doesn't exist, call `git submodule update --init --recursive` - if !dir.2 { - // run the command in a child process in the directory of the project - let output = std::process::Command::new("git") - .arg("submodule") - .arg("update") - .arg("--init") - .arg("--recursive") - .current_dir(CONFIG.project_path.clone()) - .output(); - - // print the output - match output { - Ok(output) => { - if output.status.success() { - missing_submodule = true - } else { - eprintln!("Command executed with failing error code"); - missing_submodule = true - } - } - Err(_) => { - eprintln!("Failed to run git submodule update --init --recursive"); - missing_submodule = true - } - } - } - } - - // return if a submodule was missing - missing_submodule -} - -// ## delete_all_submodules() -// This function deletes all submodules to allow a clean re-initialization -// of the submodules -// -// ### arguments: -// - nothing -// -// ### returns: -// - bool - true if the deletion was successful, false if not -pub fn delete_all_submodules() -> bool { - // get the submodule paths - let sub_module_paths = get_submodule_paths(); - - let mut success = false; - - // delete all submodules - for dir in sub_module_paths { - // delete the directory - let removed_dir = - std::fs::remove_dir_all(format!("{}/{}", CONFIG.project_path.clone(), dir.1)); - - match removed_dir { - Ok(_) => { - println!("Removed submodule {}", dir.0); - success = true; - } - Err(_) => { - eprintln!("Failed to remove submodule {}", dir.0); - success = false; - } - } - } - - // return the outcome of the deletion - success -} diff --git a/src/controller/mod.rs b/src/controller/mod.rs deleted file mode 100644 index 7127b20..0000000 --- a/src/controller/mod.rs +++ /dev/null @@ -1,193 +0,0 @@ -use crate::helpers; -use crate::CONFIG; -mod down; -mod init; -mod new; -mod setup; -mod up; -mod watch; - -/// ## run() -/// This function is the entry point for the controller module. -/// It takes a command and a list of arguments and runs the -/// appropriate function. -/// -/// ### Arguments -/// - command: String - The command to run -/// - args: &[String] - A list of arguments to pass to the command -/// -/// ### Returns -/// This function does not return anything -pub fn run(command: String, args: &[String]) { - match command.as_str() { - "down" => down(args), - "init" => init(args), - "up" => up(args), - "watch" => watch(args), - "status" => status(args), - "-v" | "--version" => { - // print the version number of the program - println!("Tools Version: {}", env!("CARGO_PKG_VERSION")); - println!("Project Version: {}", CONFIG.get_version()); - } - _ => { - helpers::help::main_help::print_help(); - } - } -} - -// Controller actions - -/// ## down() -/// This function stops the project using `docker compose down` -/// to stop the project. -/// -/// ### Arguments -/// - args: &[String] - A list of arguments to pass to the command -/// -/// ### Returns -/// This function does not return anything -pub fn down(args: &[String]) { - println!("Not implemented up yet"); - match args.get(0) { - Some(arg0) => match arg0.as_str() { - // print the help message for the new command - "help" | "-h" | "--help" => helpers::help::help_not_implemented_yet(), - // if the argument is not recognized, print the help message for the new command - _ => helpers::help::help_not_implemented_yet(), - }, - None => { - // if no arguments are passed, print the help message for the new command - helpers::help::help_not_implemented_yet(); - } - } -} - -/// ## init() -/// This function initializes the project and creates the necessary -/// files and directories for the project. It also bootstraps the -/// project configs and secrets from the template files. -/// -/// ### Arguments -/// - args: &[String] - A list of arguments to pass to the command -/// -/// ### Returns -/// This function does not return anything -pub fn init(args: &[String]) { - match args.get(0) { - Some(arg0) => match arg0.as_str() { - // rebuild_full performs a clean and then a init to rebuild the project - // from scratch, it takes an argument to confirm the rebuild - "rebuild" => init::rebuild_full(&args[1..]), - // clean takes arguments to confirm the deletion - "clean" => init::clean(&args[1..]), - // print the help message for the init command - "help" | "-h" | "--help" => helpers::help::init_help::print_help(), - // if the argument is not recognized, print the help message for the init command - _ => helpers::help::init_help::print_help(), - }, - None => { - // if no arguments are passed, run the init command with no arguments - init::init(); - } - } -} - -// ## new() -// This function creates a new submodule for the project -// -// ### Arguments -// - args: &[String] - A list of arguments to pass to the command -// -// ### Returns -// This function does not return anything -pub fn new(args: &[String]) { - println!("Not implemented up yet"); - match args.get(0) { - Some(arg0) => match arg0.as_str() { - // print the help message for the new command - "help" | "-h" | "--help" => helpers::help::help_not_implemented_yet(), - // if the argument is not recognized, print the help message for the new command - _ => helpers::help::help_not_implemented_yet(), - }, - None => { - // if no arguments are passed, print the help message for the new command - helpers::help::help_not_implemented_yet(); - } - } -} - -/// ## up() -/// This function starts the project using `docker compose up -d` -/// to run the project in the background. -/// -/// ### Arguments -/// - args: &[String] - A list of arguments to pass to the command -/// -/// ### Returns -/// This function does not return anything -pub fn up(args: &[String]) { - println!("Not implemented up yet"); - match args.get(0) { - Some(arg0) => match arg0.as_str() { - // print the help message for the new command - "help" | "-h" | "--help" => helpers::help::help_not_implemented_yet(), - // if the argument is not recognized, print the help message for the new command - _ => helpers::help::help_not_implemented_yet(), - }, - None => { - // if no arguments are passed, print the help message for the new command - helpers::help::help_not_implemented_yet(); - } - } -} - -/// ## watch() -/// This function brings up the project and watches for changes in -/// the application code and restarts the project when changes are -/// detected using `docker compose up -d` and `docker compose down`. -/// -/// ### Arguments -/// - args: &[String] - A list of arguments to pass to the command -/// -/// ### Returns -/// This function does not return anything -pub fn watch(args: &[String]) { - println!("Not implemented up yet"); - match args.get(0) { - Some(arg0) => match arg0.as_str() { - // print the help message for the new command - "help" | "-h" | "--help" => helpers::help::help_not_implemented_yet(), - // if the argument is not recognized, print the help message for the new command - _ => helpers::help::help_not_implemented_yet(), - }, - None => { - // if no arguments are passed, print the help message for the new command - helpers::help::help_not_implemented_yet(); - } - } -} - -// ## status() -// This function prints the status of the project -// -// ### Arguments -// - args: &[String] - A list of arguments to pass to the command -// -// ### Returns -// This function does not return anything -pub fn status(args: &[String]) { - println!("Not implemented up yet"); - match args.get(0) { - Some(arg0) => match arg0.as_str() { - // print the help message for the new command - "help" | "-h" | "--help" => helpers::help::help_not_implemented_yet(), - // if the argument is not recognized, print the help message for the new command - _ => helpers::help::help_not_implemented_yet(), - }, - None => { - // if no arguments are passed, print the help message for the new command - helpers::help::help_not_implemented_yet(); - } - } -} diff --git a/src/controller/new/mod.rs b/src/controller/new/mod.rs deleted file mode 100644 index e69de29..0000000 diff --git a/src/controller/setup/mod.rs b/src/controller/setup/mod.rs deleted file mode 100644 index e69de29..0000000 diff --git a/src/controller/up/mod.rs b/src/controller/up/mod.rs deleted file mode 100644 index e69de29..0000000 diff --git a/src/controller/watch/mod.rs b/src/controller/watch/mod.rs deleted file mode 100644 index e69de29..0000000 diff --git a/src/helpers/config/app_config/mod.rs b/src/helpers/config/app_config/mod.rs deleted file mode 100644 index dd8dffe..0000000 --- a/src/helpers/config/app_config/mod.rs +++ /dev/null @@ -1,133 +0,0 @@ -use semver::{Prerelease, Version}; - -use crate::helpers::filesystem::path::append_path; -use crate::models::app_config::AppConfigFile; -use std::env::current_dir; -use std::{fs::File, io::Write, path::Path}; - -/// Retrieves the application configuration, either by reading it from a YAML file -/// or by creating a default configuration if the file does not exist. -/// -/// ## Returns -/// - `AppConfigFile`: The application configuration. -/// -/// ## Panics -/// - If the configuration file cannot be read. -/// - If the configuration file content cannot be deserialized. -/// - If the configuration file cannot be created. -/// - If the configuration cannot be serialized to YAML. -/// - If the YAML data cannot be written to the file. -pub fn get_config() -> AppConfigFile { - let config_file = "config.yaml"; - - // get current directory path - let current_dir = current_dir().expect("Couldn't get current directory"); - - // get the path to the configuration file - let config_path = append_path(¤t_dir, config_file); - - // Check if the configuration file already exists - if !config_path.exists() { - // If the file does not exist, create a default configuration - let config = AppConfigFile::default(); - - // Write the configuration to a YAML file - write_config(&config); - - // Return the configuration - config - } else { - // If the file exists, read the configuration from the file - let raw_config_file = - std::fs::read_to_string(config_path).expect("Couldn't read config file"); - - // Deserialize the configuration from YAML - let config_file = AppConfigFile::from_yaml(&raw_config_file); - - match config_file { - Ok(config) => config, - Err(e) => { - println!("Couldn't deserialize config file: {}", e); - std::process::exit(1); - } - } - } -} - -/// Writes the application configuration to a YAML file. -/// -/// ## Arguments -/// - `config: &AppConfigFile`: A reference to the application configuration. -/// -/// ## Panics -/// - If the file cannot be created. -/// - If the configuration cannot be serialized to YAML. -/// - If the YAML data cannot be written to the file. -pub fn write_config(config: &AppConfigFile) { - // Serialize the configuration to a YAML string - let config_yaml = config.to_yaml().expect("Couldn't serialize config to YAML"); - - // Create the YAML file - let mut file = File::create(Path::new("config.yaml")).expect("Couldn't create file"); - - // Write the YAML string to the file - file.write_all(config_yaml.as_bytes()) - .expect("Couldn't write config to file"); -} - -/// Create a default configuration file. -/// -/// ## Arguments -/// - `config_file: &str`: The path to the configuration file. -/// -/// ## Returns -/// - `AppConfigFile`: The default configuration. -pub fn create_config(config_file: &str) -> AppConfigFile { - // get current directory path - let current_dir = current_dir().expect("Couldn't get current directory"); - - // get the path to the configuration file - let config_path = append_path(¤t_dir, config_file); - - // If the file does not exist, create a default configuration - let version = Version { - major: 0, - minor: 1, - patch: 0, - pre: Prerelease::new("alpha").unwrap(), - build: semver::BuildMetadata::EMPTY, - } - .to_string(); - let config = AppConfigFile { - project_path: current_dir.to_str().unwrap().to_string(), - docker_compose: "docker-compose.yaml".to_string(), - project_name: "project".to_string(), - project_version: version, - github_api_token: None, - }; - - // Write the default configuration to a YAML file - write_config(&config); - - // Return the default configuration - config -} - -/// Check if the configuration file exists. -/// -/// ## Returns -/// - `bool`: `true` if the configuration file exists, `false` otherwise. -pub fn check_if_config_exists() -> bool { - // get current directory path - let current_dir = current_dir().expect("Couldn't get current directory"); - - // get the path to the configuration file - let config_path = append_path(¤t_dir, "config.yaml"); - - // Check if the configuration file already exists - if !config_path.exists() { - false - } else { - true - } -} diff --git a/src/helpers/config/mod.rs b/src/helpers/config/mod.rs deleted file mode 100644 index 62a6f82..0000000 --- a/src/helpers/config/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod app_config; diff --git a/src/helpers/docker/docker_compose/file.rs b/src/helpers/docker/docker_compose/file.rs deleted file mode 100644 index 3f719c9..0000000 --- a/src/helpers/docker/docker_compose/file.rs +++ /dev/null @@ -1,53 +0,0 @@ -use crate::helpers::filesystem::path::append_path; -use crate::models::docker_compose::DockerCompose; -use crate::CONFIG; -use std::fs::read_to_string; -use std::path::PathBuf; - -/// ## get_path_to_docker_compose() -> PathBuf -/// This function returns a PathBuf to the docker compose file -/// -/// ### Returns -/// - PathBuf -fn get_path_to_docker_compose() -> PathBuf { - let raw_project_path = &CONFIG.project_path; - let project_path = PathBuf::from(raw_project_path); - let docker_compose_filename = &CONFIG.docker_compose; - append_path(&project_path, docker_compose_filename) -} - -/// ## get_docker_compose_file() -> DockerCompose -/// This function returns a DockerComposeFile struct from a yaml string -/// -/// ### Returns -/// - DockerComposeFile -pub fn get_docker_compose_file() -> DockerCompose { - // get absolute path to docker compose file - let docker_compose_path = get_path_to_docker_compose(); - - // read docker compose into DockerCompose struct - let docker_compose = DockerCompose::from_yaml( - &read_to_string(docker_compose_path) - .expect("Could not read docker compose file into string"), - ); - - match docker_compose { - Ok(docker_compose) => docker_compose, - Err(error) => panic!("Could not parse docker compose file: {}", error), - } -} - -/// ## write_docker_compose_file(docker_compose: &DockerCompose) -> bool -/// This function writes a DockerCompose struct to the docker compose file -/// -/// ### Arguments -/// - docker_compose: &DockerCompose - DockerCompose struct to write to file -/// -/// ### Returns -/// - bool: true if successful, false if not -pub fn write_docker_compose_file(docker_compose: &DockerCompose) -> bool { - let docker_compose_path = get_path_to_docker_compose(); - let docker_compose_yaml = docker_compose.to_yaml().unwrap(); - std::fs::write(docker_compose_path, docker_compose_yaml).unwrap(); - true -} diff --git a/src/helpers/docker/docker_compose/mod.rs b/src/helpers/docker/docker_compose/mod.rs deleted file mode 100644 index 0373c10..0000000 --- a/src/helpers/docker/docker_compose/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod file; -//mod add_network; -//mod add_secret; -//mod add_service; -//mod add_volume; diff --git a/src/helpers/docker/mod.rs b/src/helpers/docker/mod.rs deleted file mode 100644 index bc2f859..0000000 --- a/src/helpers/docker/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod docker_compose; diff --git a/src/helpers/filesystem/dir.rs b/src/helpers/filesystem/dir.rs deleted file mode 100644 index be1c13d..0000000 --- a/src/helpers/filesystem/dir.rs +++ /dev/null @@ -1,116 +0,0 @@ -use crate::CONFIG; - -/// ## get_directories(path: Option<&str>) -/// Recursively gets all directories in the root path and defaults to . if no path is provided -/// -/// ### Arguments -/// - path: Option<&str> - The path to get directories from (defaults to .) -/// -/// ### Returns -/// - Vec - A vector of strings containing the directories -#[allow(dead_code)] -pub fn get_directories(path: Option<&str>) -> Vec { - let mut directories: Vec = Vec::new(); - let path = path.unwrap_or("."); - let paths = std::fs::read_dir(path).unwrap(); - for path in paths { - let path = path.unwrap().path(); - if path.is_dir() { - directories.push(path.display().to_string()); - directories.append(&mut get_directories(Some( - path.display().to_string().as_str(), - ))); - } - } - directories -} - -/// ## check_if_directory_exists(path: &str) -/// This function checks if a directory exists -/// -/// ### Arguments -/// - path: &str - The path to the directory -/// -/// ### Returns -/// - bool - Whether or not the directory exists -pub fn check_if_directory_exists(path: &str) -> bool { - // check if path is from root, if not, prepend the project path - let path = if path.starts_with('/') { - path.to_string() - } else { - format!("{}/{}", CONFIG.project_path, path) - }; - - let path = std::path::Path::new(&path); - path.exists() -} - -/// ## create_directory(path: &str) -/// This function creates a directory -/// -/// ### Arguments -/// - path: &str - The path to the directory -/// -/// ### Returns -/// - bool - Whether or not the directory was created -#[allow(dead_code)] -pub fn create_directory(path: &str) -> bool { - let path = std::path::Path::new(path); - std::fs::create_dir(path).is_ok() -} - -/// # (THIS FUNCTION IS DANGEROUS AND SHOULD BE USED WITH *EXTREME* CAUTION) -/// ## recursively_delete_directory(path: &str) -/// This function recursively deletes a directory -/// -/// ### Arguments -/// - path: &str - The path to the directory -/// -/// ### Returns -/// - bool - Whether or not the directory was deleted -#[allow(dead_code)] -pub fn recursively_delete_directory(path: &str) -> bool { - let path = std::path::Path::new(path); - std::fs::remove_dir_all(path).is_ok() -} - -/// ## get_absolute_path(path: &str) -/// This function gets the absolute path of a directory -/// -/// ### Arguments -/// - path: &str - The path to the directory -/// -/// ### Returns -/// - String - The absolute path of the directory -pub fn get_absolute_path(path: &str) -> String { - // check if the path starts with root, and if not, prepend the project path - if path.starts_with('/') { - path.to_string() - } else { - format!("{}/{}", CONFIG.project_path, path) - } -} - -/// ## map_dirs(list_dirs: Vec) -> Vec<(String, String, bool)> -/// This function maps a list of directories to a tuple of the absolute path, the path, and if the directory exists -/// -/// ### Arguments -/// - list_dirs: Vec - A list of directories -/// -/// ### Returns -/// - Vec<(String, String, bool)> - A vector of tuples containing the absolute path, the path, and if the directory exists -pub fn map_dirs(list_dirs: Vec) -> Vec<(String, String, bool)> { - let maped_dirs = list_dirs - .iter() - .map(|path| { - // return the tuple - ( - get_absolute_path(path), - path.clone(), - check_if_directory_exists(path.as_str()), - ) - }) - .collect::>(); - - maped_dirs -} diff --git a/src/helpers/filesystem/file.rs b/src/helpers/filesystem/file.rs deleted file mode 100644 index 9715aa6..0000000 --- a/src/helpers/filesystem/file.rs +++ /dev/null @@ -1,35 +0,0 @@ -/// ## list_files(path: &str) -/// Lists all files in a given directory -/// -/// # Arguments -/// path: &str - The path to the directory to list files in -/// -/// # Returns -/// Vec - A vector of strings containing the files -#[allow(dead_code)] -pub fn list_files(path: &str) -> Vec { - let mut files: Vec = Vec::new(); - let paths = std::fs::read_dir(path).unwrap(); - for path in paths { - let path = path.unwrap().path(); - if path.is_file() { - files.push(path.display().to_string()); - } - } - files -} - -/// ## read_file(file: &str) -/// This function reads a file and returns a list of lines in the file -/// -/// ## Arguments -/// - file: &str - The path to the file to read -/// -/// ## Returns -/// - Vec - A vector of strings containing the lines in the file -#[allow(dead_code)] -pub fn read_file(file: &str) -> Vec { - let contents = std::fs::read_to_string(file).expect("Something went wrong reading the file"); - let lines: Vec = contents.lines().map(|s| s.to_string()).collect(); - lines -} diff --git a/src/helpers/filesystem/mod.rs b/src/helpers/filesystem/mod.rs deleted file mode 100644 index 8f5cb0b..0000000 --- a/src/helpers/filesystem/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod dir; -pub mod file; -pub mod path; diff --git a/src/helpers/filesystem/path.rs b/src/helpers/filesystem/path.rs deleted file mode 100644 index 82a5ff7..0000000 --- a/src/helpers/filesystem/path.rs +++ /dev/null @@ -1,25 +0,0 @@ -/// ## get_path(path: &str) -/// This function gets the path of a file or directory -/// -/// ## Arguments -/// - path: &str - The path to the file or directory -/// -/// ## Returns -/// - PathBuf - The path to the file or directory -#[allow(dead_code)] -pub fn get_path(path: &str) -> std::path::PathBuf { - std::fs::canonicalize(path).unwrap() -} - -/// ## append_path(base_path: &PathBuf, file: &str) -/// This function appends a file or directory to a path -/// -/// ## Arguments -/// - base_path: &PathBuf - The base path to append the file or directory to -/// - file: &str - The file or directory to append to the base path -/// -/// ## Returns -/// - PathBuf - The path to the file or directory -pub fn append_path(base_path: &std::path::PathBuf, file: &str) -> std::path::PathBuf { - base_path.join(file) -} diff --git a/src/helpers/git/mod.rs b/src/helpers/git/mod.rs deleted file mode 100644 index e69de29..0000000 diff --git a/src/helpers/help/init_help.rs b/src/helpers/help/init_help.rs deleted file mode 100644 index 684ade1..0000000 --- a/src/helpers/help/init_help.rs +++ /dev/null @@ -1,17 +0,0 @@ -//multiline variable for the main help file -pub const INIT_HELP: &str = r#" -Usage: - tools init [OPTIONS] [Subcommand] - -Options: - -h, --help Prints help information - -Subcommands: - none Initializes the project - new Creates a new project - rebuild Rebuilds the project -"#; - -pub fn print_help() { - println!("{}", INIT_HELP); -} diff --git a/src/helpers/help/main_help.rs b/src/helpers/help/main_help.rs deleted file mode 100644 index caa6306..0000000 --- a/src/helpers/help/main_help.rs +++ /dev/null @@ -1,25 +0,0 @@ -//multiline variable for the main help file -pub const MAIN_HELP: &str = r#" -Usage: - tools [command] [subcommand] [arguments] - -Arguments: - help, -h, --help Prints this help message - version, --version Prints the version of the program - -v(#) Sets the verbosity level of the program (0-5) (default: 3) - (Not implemented yet) - -q Sets the verbosity level to 0 (same as -v0) - (Not implemented yet) - -Commands: - down Stops the project - (Not implemented yet) - init Initializes the project - up Starts the project - (Not implemented yet) - watch Starts the project and watches for changes - (Not implemented yet) - status Prints the status of the project - (Not implemented yet) - -For more information on a command, run `tools help [command] - -"#; - -pub fn print_help() { - println!("{}", MAIN_HELP); -} diff --git a/src/helpers/help/mod.rs b/src/helpers/help/mod.rs deleted file mode 100644 index 5f7cc64..0000000 --- a/src/helpers/help/mod.rs +++ /dev/null @@ -1,23 +0,0 @@ -pub mod init_help; -pub mod main_help; - -pub fn router(args: &[String]) { - match args.get(0) { - Some(arg0) => match arg0.as_str() { - "init" => init_help::print_help(), - _ => main_help::print_help(), - }, - None => { - main_help::print_help(); - } - } -} - -// ### help_not_implemented_yet() -// This function prints a message that the help command is not implemented yet -// -// ### Returns -// This function does not return anything -pub fn help_not_implemented_yet() { - println!("Help is not implemented yet"); -} diff --git a/src/helpers/mod.rs b/src/helpers/mod.rs deleted file mode 100644 index a850773..0000000 --- a/src/helpers/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub mod config; -pub mod docker; -pub mod filesystem; -pub mod git; -pub mod help; -pub mod program_checker; -pub mod user_input; diff --git a/src/helpers/program_checker/mod.rs b/src/helpers/program_checker/mod.rs deleted file mode 100644 index e69de29..0000000 diff --git a/src/helpers/user_input/mod.rs b/src/helpers/user_input/mod.rs deleted file mode 100644 index ac7a866..0000000 --- a/src/helpers/user_input/mod.rs +++ /dev/null @@ -1,164 +0,0 @@ -/// ## get_user_input(prompt: &str) -> String -/// This function gets user input from stdin and returns it as a String -/// it also has an optional argument to normalize the input -/// -/// ### Arguments -/// - prompt: &str - The prompt to display to the user -/// - normalize (optional) - bool - Whether or not to normalize the input -/// -/// ### Returns -/// - String - The user input -pub fn get_user_input(prompt: &str, normalize: Option) -> String { - // normalize the prompt - let normalized_prompt = normalize_prompt(prompt); - - // print the prompt - print!("{}", normalized_prompt); - - // create a new string to store the user input - let mut input = String::new(); - - // read the user input - std::io::stdin().read_line(&mut input).unwrap(); - - // check if normalize is provided, and then what it option was set too - match normalize { - Some(true) => { - // normalize the input - input = input.trim().to_string().to_ascii_lowercase(); - } - Some(false) => { - input = input.trim().to_string(); - } - None => { - input = input.trim().to_string(); - } - } - - // return the user input - input -} - -/// ## get_user_input_with_options(prompt: &str, options: &[&str]) -> bool -/// This function gets user input from stdin and returns it as a String -/// if the input matches one of the options -/// -/// This function is case insensitive and normalizes the input to lowercase ASCII -/// -/// ### Arguments -/// - prompt: &str - The prompt to display to the user -/// - options: &[&str] - A list of ASCII options to match the user input against -/// -/// ### Returns -/// - bool - true if the user input matches one of the options, false otherwise -pub fn get_user_input_with_options(prompt: &str, options: &[&str]) -> bool { - // if prompt is empty, panic - if prompt.is_empty() { - panic!("Prompt cannot be empty for get_user_input_with_options"); - } - - // normalize the prompt - let normalized_prompt = normalize_prompt(prompt); - - // print the normalized_prompt - print!("{}", normalized_prompt); - - // create a new string to store the user input - let mut input = String::new(); - - // read the user input - std::io::stdin().read_line(&mut input).unwrap(); - - // normalize the input - input = input.trim().to_string().to_ascii_lowercase(); - - // check if the user input matches one of the options - if options.contains(&input.trim()) { - // return true - true - } else { - // return false - false - } -} - -/// ## normalize_prompt(prompt: &str) -> String -/// This function normalizes the prompt by adding a colon and a space -/// to the end of the prompt if it is not already there -/// -/// ### Arguments -/// - prompt: &str - The prompt to normalize -/// -/// ### Returns -/// - String - The normalized prompt -pub fn normalize_prompt(prompt: &str) -> String { - // check if prompt is empty and set it to a default value if it is - let local_prompt = if prompt.is_empty() { - "Enter input: " - } else { - prompt // return the prompt - }; - - // trim tailing whitespace - let local_prompt = local_prompt.trim(); - - // Check 1: if the prompt ends with a letter or number add a colon and a space - // Check 2: if the prompt ends with a character that is not colon, remove it and add a colon and a space - // Check 3: if the prompt ends with a colon and a space, do nothing - if local_prompt.ends_with(|c: char| c.is_ascii_alphanumeric()) { - // add a colon and a space - format!("{}: ", local_prompt) - } else if local_prompt.ends_with(|c: char| !c.is_ascii_alphanumeric() && c != ':') { - // remove the last character and add a colon and a space - format!( - "{}: ", - local_prompt.trim_end_matches(|c: char| !c.is_ascii_alphanumeric()) - ) - } else if local_prompt.ends_with(": ") { - // do nothing - local_prompt.to_string() - } else { - // add a colon and a space - format!("{}: ", local_prompt) - } -} - -/// ## ask_user_yes_or_no(prompt: &str) -> bool -/// This function asks the user a yes or no question and returns true if the user -/// answers yes and false if the user answers no -/// This function is case insensitive and normalizes the input to lowercase ASCII -/// This function will keep asking the user for input until they answer yes or no -/// -/// ### Arguments -/// - prompt: &str - The prompt to display to the user -/// -/// ### Returns -/// - bool - true if the user answers yes, false if the user answers no -pub fn ask_user_yes_or_no(prompt: &str) -> bool { - // create a new string to store the user input - let mut input = String::new(); - - // loop until the user answers yes or no - loop { - // get the user input - input = get_user_input(prompt, Some(true)); - - // check if the user input is yes or no - if input == "yes" || input == "no" { - // break out of the loop - break; - } else { - // print an error message - println!("Please enter yes or no"); - } - } - - // check if the user input is yes - if input == "yes" { - // return true - true - } else { - // return false - false - } -} diff --git a/src/main.rs b/src/main.rs index b15a7db..3ac0d22 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,9 @@ -use crate::{helpers::config, models::app_config::AppConfigFile}; -use once_cell::sync::Lazy; +// use crate::models::app_config::AppConfigFile; +// use once_cell::sync::Lazy; -/// This is the main file for the program -mod controller; -mod helpers; mod models; -pub static CONFIG: Lazy = Lazy::new(config::app_config::get_config); +//pub static CONFIG: Lazy = Lazy::new(); /// ## main() /// This function is the entry point for the program diff --git a/src/models/app_config/mod.rs b/src/models/app_config/mod.rs index aa6964b..7d333d8 100644 --- a/src/models/app_config/mod.rs +++ b/src/models/app_config/mod.rs @@ -156,7 +156,7 @@ github_token: gh_token # if you want to use github api instead of the GitHub CLI let config = AppConfigFile::from_yaml(config_yaml).unwrap(); let config_from_file = - std::fs::read_to_string("src/test/models/app_config/config.yaml").unwrap(); + std::fs::read_to_string("src/tests/models/app_config/config.yaml").unwrap(); let from_file = AppConfigFile::from_yaml(&config_from_file); match from_file { diff --git a/src/models/docker_compose/mod.rs b/src/models/docker_compose/mod.rs index 693c63e..7edcfb3 100644 --- a/src/models/docker_compose/mod.rs +++ b/src/models/docker_compose/mod.rs @@ -123,14 +123,13 @@ volumes: "#; //relative path from the project root - let path_to_test_docker_compose = "src/test/models/docker_compose/docker-compose.yaml"; + let path_to_test_docker_compose = "src/tests/models/docker_compose/docker-compose.yaml"; // get directory where this program is running let current_dir = std::env::current_dir().unwrap(); // get absolute path to path_to_test_docker_compose - let absolue_path = - crate::helpers::filesystem::path::append_path(¤t_dir, path_to_test_docker_compose); + let absolue_path = std::path::Path::new(¤t_dir).join(path_to_test_docker_compose); println!("absolue_path: {:?}", absolue_path); diff --git a/src/models/project/mod.rs b/src/models/project/mod.rs index 0e43024..87044e3 100644 --- a/src/models/project/mod.rs +++ b/src/models/project/mod.rs @@ -1,6 +1,6 @@ use semver::{BuildMetadata, Prerelease, Version}; use serde::{Deserialize, Serialize}; -use std::{error::Error, fs}; +use std::error::Error; /// This struct represents the structure of the project and /// is used to serialize and deserialize the project definition file. @@ -150,7 +150,8 @@ services: #[test] fn test_project_read_from_file() { - let project_from_file = fs::read_to_string("src/test/models/project/project.yaml").unwrap(); + let project_from_file = + std::fs::read_to_string("src/tests/models/project/project.yaml").unwrap(); let from_file = Project::from_yaml(&project_from_file); diff --git a/src/models/repository/mod.rs b/src/models/repository/mod.rs index ba2dfc0..6504dc8 100644 --- a/src/models/repository/mod.rs +++ b/src/models/repository/mod.rs @@ -1,4 +1,4 @@ -use std::{error::Error, fs}; +use std::error::Error; use serde::{Deserialize, Serialize}; @@ -146,8 +146,13 @@ fn test_creating_a_repository_from_json_string_with_invalid_json() { #[test] fn test_reading_a_repository_from_a_file() { - let repo_from_file = - fs::read_to_string("src/test/models/repository/example_api_call.json").unwrap(); + let current_dir = std::env::current_dir().unwrap(); + + let repo_from_file = std::fs::read_to_string( + std::path::Path::new(¤t_dir) + .join("src/tests/models/repository/example_api_call.json"), + ) + .expect("Unable to read the file."); let repo_from_json = Repository::from_json(&repo_from_file); diff --git a/src/test/main.rs b/src/test/main.rs deleted file mode 100644 index b133921..0000000 --- a/src/test/main.rs +++ /dev/null @@ -1 +0,0 @@ -use models::config::Config; diff --git a/src/test/models/app_config/config.yaml b/src/tests/models/app_config/config.yaml similarity index 100% rename from src/test/models/app_config/config.yaml rename to src/tests/models/app_config/config.yaml diff --git a/src/test/models/docker b/src/tests/models/docker similarity index 100% rename from src/test/models/docker rename to src/tests/models/docker diff --git a/src/test/models/docker_compose/docker-compose.yaml b/src/tests/models/docker_compose/docker-compose.yaml similarity index 100% rename from src/test/models/docker_compose/docker-compose.yaml rename to src/tests/models/docker_compose/docker-compose.yaml diff --git a/src/test/models/project/project.yaml b/src/tests/models/project/project.yaml similarity index 100% rename from src/test/models/project/project.yaml rename to src/tests/models/project/project.yaml diff --git a/src/test/models/repository/example_api_call.json b/src/tests/models/repository/example_api_call.json similarity index 100% rename from src/test/models/repository/example_api_call.json rename to src/tests/models/repository/example_api_call.json