diff --git a/Cargo.toml b/Cargo.toml index b1e1a52..03132a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,8 +10,8 @@ clap = { version = "4.2.4", features = ["derive"] } dylib = "0.0.3" flate2 = "1.0.25" indicatif = "0.17.3" -reqwest = "0.11.16" +reqwest = "0.11.17" serde = { version = "1.0.160", features = ["derive"] } serde_yaml = "0.9.21" tar = "0.4.38" -tokio = { version = "1.16.1", features = ["full"] } +tokio = { version = "1.28.0", default_features = false, features = ["full"] } diff --git a/src/args.rs b/src/args.rs index da868bc..0bb12d9 100644 --- a/src/args.rs +++ b/src/args.rs @@ -3,9 +3,9 @@ use clap::Parser; #[derive(Debug, Parser)] #[clap(author, version, about)] pub struct SandboxArgs { - /// Create a New Beach + /// Create a New Environment #[clap(short = 'n', long = "new", default_value = "")] - pub beach_type: String, + pub new: String, /// Search for Environment #[clap(short = 'S', long, default_value = "")] diff --git a/src/download.rs b/src/download.rs index c92248c..95a1c95 100644 --- a/src/download.rs +++ b/src/download.rs @@ -4,20 +4,20 @@ use std::io; use std::path::Path; use std::thread; use std::time::Duration; +use std::fs; use std::{cmp::min, fmt::Write}; use reqwest::Client; use flate2::read::GzDecoder; use tar::Archive; -use tokio::fs; use indicatif::{ProgressBar, ProgressState, ProgressStyle}; use crate::get_path; pub async fn download_environment(id: String) -> Result<(), Box> { let base_path = "/usr/share/sandbox/beaches/"; - let environment_path = get_path(id.clone()); + let environment_path = get_path(id.clone()).await; let download_url = format!("https://github.com/the-sandbox-project/sandbox-templates/raw/master/{}", environment_path); let download_path = format!("{}{}", base_path, environment_path); @@ -28,7 +28,7 @@ pub async fn download_environment(id: String) -> Result<(), Box> { if response.status().is_success() { let language_path = Path::new(&download_path).parent().unwrap().to_str().unwrap(); - fs::create_dir_all(language_path).await?; + fs::create_dir_all(language_path)?; let mut file = File::create(&download_path)?; @@ -61,9 +61,9 @@ pub async fn download_environment(id: String) -> Result<(), Box> { let mut archive = Archive::new(tar); archive.unpack(&unzip_path)?; - fs::remove_file(&download_path).await?; + fs::remove_file(&download_path)?; - println!("Installed {}! Run it with: sandbox --new {}", id, id) + println!("Installed {}! Test it out with: sandbox --new {}", id, id) } Ok(()) } diff --git a/src/editor.rs b/src/editor.rs index aa29e3e..ff8bfed 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -1,17 +1,8 @@ -use std::process::Command; -use std::process::exit; - use crate::config::read_config_file; pub fn get_editor() -> String { let config = read_config_file().unwrap(); - let editor = config.editor.editor_name; - match Command::new(&editor).status() { - Ok(_) => editor, - Err(_) => { - println!("[ERROR] EDITOR_NOT_FOUND: There was an Error Running the Editor: {}. Check your sandbox.yml Config.", editor); - exit(1); - } - } + let editor = config.editor.editor_name; + editor } diff --git a/src/environment.rs b/src/environment.rs index 70210b6..6754d81 100644 --- a/src/environment.rs +++ b/src/environment.rs @@ -1,13 +1,15 @@ -use std::fs; use std::process::Command; use std::env; use crate::editor::get_editor; +use crate::get_path; -pub fn open_environment(environment: String) { +pub async fn open_environment(environment: String) { let editor = get_editor(); - let beaches_path = format!("/usr/share/sandbox/beaches/{}", environment); + let path = get_path(environment.clone()).await; + let environment_path = path.split("/").collect::>()[0].to_owned() + "/" + &environment; + let beaches_path = format!("/usr/share/sandbox/beaches/{}", environment_path); env::set_current_dir(beaches_path).unwrap(); Command::new(editor) @@ -18,16 +20,3 @@ pub fn open_environment(environment: String) { .unwrap(); } -pub fn setup_environment(environment: String) { - let beaches_path = format!("/usr/share/sandbox/beaches/{}", environment); - - let environment_exists = match fs::metadata(beaches_path) { - Ok(_) => true, - Err(_) => false, - }; - - if environment_exists { - open_environment(environment) - } else { - } -} diff --git a/src/install.rs b/src/install.rs index 519396d..55417ab 100644 --- a/src/install.rs +++ b/src/install.rs @@ -3,8 +3,8 @@ use std::path::Path; use crate::{get_path, id_is_valid, download::download_environment}; pub async fn install_environment(id: String) { - if id_is_valid(id.clone()) { - if in_system(id.clone()) { + if id_is_valid(id.clone()).await { + if in_system(id.clone()).await { println!("You already have {} installed on your system!", id); } else { download_environment(id.clone()).await.unwrap(); @@ -14,8 +14,8 @@ pub async fn install_environment(id: String) { } } -pub fn in_system(id: String) -> bool { - let path = get_path(id.clone()); +pub async fn in_system(id: String) -> bool { + let path = get_path(id.clone()).await; let environment_path = path.split("/").collect::>()[0].to_owned() + "/" + &id; let formatted_path = format!("/usr/share/sandbox/beaches/{}", environment_path); diff --git a/src/lib.rs b/src/lib.rs index 876b1b9..fa8b17b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,26 +5,28 @@ mod environment; mod search; mod install; mod download; +mod new; -use std::fs; +use std::error::Error; use args::SandboxArgs; use search::search; -use environment::setup_environment; use install::install_environment; +use new::create_new_environment; use clap::Parser; use serde_yaml::{Value, Mapping}; +use reqwest::Url; pub async fn run() { let args = SandboxArgs::parse(); - if !args.search.is_empty() { - search(args.search) + if !args.new.is_empty() { + create_new_environment(args.new).await } - if !args.beach_type.is_empty() { - setup_environment(args.beach_type) + if !args.search.is_empty() { + search(args.search).await } if !args.install.is_empty() { @@ -32,19 +34,21 @@ pub async fn run() { } } -pub fn get_templates_mapping() -> Mapping { - let sandbox_templates_path = "../sandbox-templates/sandbox-templates.yml"; - let file_contents = fs::read_to_string(sandbox_templates_path).unwrap(); - let templates: Value = serde_yaml::from_str(&file_contents).unwrap(); +pub async fn get_templates_mapping() -> Result> { + let url = Url::parse("https://raw.githubusercontent.com/the-sandbox-project/sandbox-templates/master/sandbox-templates.yml")?; + let response = reqwest::get(url).await?.text().await?; + + let templates: Value = serde_yaml::from_str(response.as_str()).unwrap(); if let Some(languages) = templates["languages"].as_mapping() { - return languages.to_owned() + Ok(languages.to_owned()) + } else { + Ok(Mapping::new()) } - Mapping::new() } -pub fn get_title(id: String) -> String { - for (_language, project_list) in get_templates_mapping() { +pub async fn get_title(id: String) -> String { + for (_language, project_list) in get_templates_mapping().await.unwrap() { if let Some(project) = project_list.as_mapping() { if let Some(list) = project.get(&id) { let path = list["title"].as_str().unwrap().to_string(); @@ -55,8 +59,8 @@ pub fn get_title(id: String) -> String { String::new() } -pub fn get_description(id: String) -> String { - for (_language, project_list) in get_templates_mapping() { +pub async fn get_description(id: String) -> String { + for (_language, project_list) in get_templates_mapping().await.unwrap() { if let Some(project) = project_list.as_mapping() { if let Some(list) = project.get(&id) { let path = list["description"].as_str().unwrap().to_string(); @@ -67,8 +71,8 @@ pub fn get_description(id: String) -> String { String::new() } -pub fn get_path(id: String) -> String { - for (_language, project_list) in get_templates_mapping() { +pub async fn get_path(id: String) -> String { + for (_language, project_list) in get_templates_mapping().await.unwrap() { if let Some(project) = project_list.as_mapping() { if let Some(list) = project.get(&id) { let path = list["path"].as_str().unwrap().to_string(); @@ -79,8 +83,8 @@ pub fn get_path(id: String) -> String { String::new() } -pub fn get_keywords(id: String) -> String { - for (_language, project_list) in get_templates_mapping() { +pub async fn get_keywords(id: String) -> String { + for (_language, project_list) in get_templates_mapping().await.unwrap() { if let Some(project) = project_list.as_mapping() { if let Some(list) = project.get(&id) { let path = list["keywords"].as_str().unwrap().to_string(); @@ -91,8 +95,8 @@ pub fn get_keywords(id: String) -> String { String::new() } -pub fn get_project_object(id: String) -> Value { - for (_language, project_list) in get_templates_mapping() { +pub async fn get_project_object(id: String) -> Value { + for (_language, project_list) in get_templates_mapping().await.unwrap() { if let Some(project) = project_list.as_mapping() { if let Some(list) = project.get(&id) { return list.to_owned() @@ -102,8 +106,8 @@ pub fn get_project_object(id: String) -> Value { Value::Null } -pub fn id_is_valid(id: String) -> bool{ - for (_language, project_list) in get_templates_mapping() { +pub async fn id_is_valid(id: String) -> bool{ + for (_language, project_list) in get_templates_mapping().await.unwrap() { if let Some(project) = project_list.as_mapping() { if let Some(_) = project.get(&id) { return true diff --git a/src/new.rs b/src/new.rs new file mode 100644 index 0000000..98d7a32 --- /dev/null +++ b/src/new.rs @@ -0,0 +1,10 @@ +use crate::id_is_valid; +use crate::environment::open_environment; + +pub async fn create_new_environment(environment: String) { + if id_is_valid(environment.clone()).await { + open_environment(environment).await + } else { + println!("The environment {} does not exist?", environment) + } +} diff --git a/src/search.rs b/src/search.rs index 5dbc1c0..d779369 100644 --- a/src/search.rs +++ b/src/search.rs @@ -1,17 +1,21 @@ use crate::install::in_system; use crate::get_templates_mapping; -pub fn search(query: String) { - println!("Environments That Match Query {}\n", query); - - search_environment(query); - - println!("\nInstall any of these with sandbox install ") +pub async fn search(query: String) { + let matching_environments_exist = search_environment(query.clone()).await; + + if matching_environments_exist { + println!("\nEnvironments That Match Query {}", query); + println!("Install any of these with sandbox install ") + } else { + println!("No Environments Found for Query: {}", query) + } } -pub fn search_environment(query: String) { - let _sandbox_url = "https://raw.githubusercontent.com/the-sandbox-project/sandbox-templates/master/sandbox-templates.yml"; - for (_language, project) in get_templates_mapping() { +pub async fn search_environment(query: String) -> bool { + let mut matching_environments_exist = false; + + for (_language, project) in get_templates_mapping().await.unwrap() { for (project_id, project_object) in project.as_mapping().unwrap() { let keywords = project_object["keywords"].as_str().unwrap_or(""); let keywords_list: Vec<&str> = keywords.split_whitespace().collect(); @@ -22,15 +26,19 @@ pub fn search_environment(query: String) { let description = project_object["description"].as_str().unwrap_or("Description not Found"); let id = project_id.as_str().unwrap().to_string(); - let installed = match in_system(id.clone()) { + let installed = match in_system(id.clone()).await { true => "✅", false => "❌" }; - println!(" {} {} ({}) - {}", installed, title, id, description) + matching_environments_exist = true; + + println!(" {} {} ({}) - {}", installed, title, id, description); + } } } } + matching_environments_exist }