Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Clear Cache & Reinstall Arguments #13

Merged
merged 13 commits into from
May 3, 2023
Merged
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
[package]
name = "sandbox"
version = "0.1.1"
version = "0.2.1"
edition = "2021"
authors = ["WillKirkmanM <[email protected]>"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
clap = { version = "4.2.4", features = ["derive"] }
clap = { version = "4.2.7", features = ["derive"] }
colored = "2.0.0"
flate2 = "1.0.26"
indicatif = "0.17.3"
Expand Down
17 changes: 13 additions & 4 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,25 @@ pub struct SandboxArgs {
#[clap(short, long, default_value = "")]
pub new: String,

/// Create a New Environment
#[clap(short = 'U', long, default_value = "")]
pub uninstall: String,

/// Search for Environment
#[clap(short = 'S', long, default_value = "")]
pub search: String,

/// Search for Environment
#[clap(short = 'I', long, default_value = "")]
pub install: String,

/// Create a New Environment
#[clap(short = 'U', long, default_value = "")]
pub uninstall: String,

/// Reinstall an Environment
#[clap(short = 'R', long)]
pub reinstall: String,

/// Clear the Install Cache
#[clap(short = 'C', long)]
pub clearcache: bool,

}

41 changes: 41 additions & 0 deletions src/cache.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use std::path::Path;

use tokio::fs;
use colored::Colorize;

use crate::{get_path, get_cache_path};

pub async fn ensure_installed() {
let cache_path = get_cache_path();

fs::create_dir_all(cache_path).await.unwrap();
}

pub async fn clear_cache() {
let cache_path = get_cache_path();

let cache_folder_is_empty = fs::read_dir(&cache_path).await.unwrap().next_entry().await.unwrap().is_none();

if cache_folder_is_empty {
println!("The Install Cache is {}!", "Empty".bright_green())
} else {
fs::remove_dir_all(&cache_path).await.unwrap();
fs::create_dir(&cache_path).await.unwrap();

println!("{} Cleared The Install Cache!", "Successfully".bright_green())
}
}

pub async fn in_cache(id: impl Into<String>) -> bool {
let id = id.into();

let cache_path = get_cache_path();

let environment_path = get_path(&id).await;
let tar_name = environment_path.split('/').last().unwrap();

let formatted_cache_path = format!("{}{}", cache_path, tar_name);
let tar_in_cache = Path::new(&formatted_cache_path).exists();

tar_in_cache
}
119 changes: 78 additions & 41 deletions src/download.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use std::path::Path;
use std::thread;
use std::time::Duration;
use std::fs;
use std::env;
use std::{cmp::min, fmt::Write};


Expand All @@ -15,66 +14,104 @@ use tar::Archive;
use indicatif::{ProgressBar, ProgressState, ProgressStyle};
use colored::Colorize;

use crate::get_beaches_path;
use crate::get_cache_path;
use crate::get_path;
use crate::cache::{self, in_cache};

pub async fn install(id: String) -> Result<(), Box<dyn Error>> {
let base_path = match env::consts::OS {
"windows" => {
let appdata = std::env::var("appdata").unwrap();
let beaches_path = format!("{}/sandbox/beaches/", appdata);
beaches_path
}
_ => "/usr/share/sandbox/beaches/".to_string()
};
pub async fn install(id: impl Into<String>) -> Result<(), Box<dyn Error>> {
let id = id.into();

let environment_path = get_path(id.clone()).await;
let base_path = get_beaches_path();
let environment_path = get_path(&id).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);

let client = Client::new();

let response = client.get(download_url).send().await?;

if response.status().is_success() {
let language_path = Path::new(&download_path).parent().unwrap().to_str().unwrap();
fs::create_dir_all(language_path)?;
let tar_name = environment_path.split('/').last().unwrap();

cache::ensure_installed().await;
let cache_path = get_cache_path();

let mut file = File::create(&download_path)?;
let formatted_cache_path = format!("{}{}", cache_path, tar_name);

let mut downloaded = 0;
let total_size = response.content_length().unwrap();
if in_cache(&id).await {
println!("{} found in {}! Installing from {}...", id.blue(), "Cache".bright_green(), "Cache".bright_green());

let pb = ProgressBar::new(total_size);
pb.set_style(ProgressStyle::with_template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta})")
.unwrap()
.with_key("eta", |state: &ProgressState, w: &mut dyn Write| write!(w, "{:.1}s", state.eta().as_secs_f64()).unwrap())
.progress_chars("#>-"));
let language_path = Path::new(&download_path).parent().unwrap().to_str().unwrap();

while downloaded < total_size {
let new = min(downloaded + 223211, total_size);
downloaded = new;
pb.set_position(new);
thread::sleep(Duration::from_millis(12));
}

pb.finish_with_message("downloaded");
let unzip_path = format!("{}/{}", language_path, id);

let content = response.bytes().await?;
fs::create_dir_all(&language_path)?;

io::copy(&mut content.as_ref(), &mut file)?;

let unzip_path = format!("{}/{}", language_path, id);
fs::copy(&formatted_cache_path, &download_path)?;

let tar_gz = File::open(&download_path)?;
let tar = GzDecoder::new(tar_gz);
let mut archive = Archive::new(tar);

archive.unpack(&unzip_path)?;

File::create(&formatted_cache_path)?;

fs::copy(&download_path, &formatted_cache_path)?;

fs::remove_file(&download_path)?;

println!("Installed {}! Test it out with: sandbox --new {}", id.bright_green(), id.bright_green())
}
Ok(())
println!("Installed {}! Test it out with: sandbox --new {}", id.bright_green(), id.bright_green());

Ok(())
} else {
let client = Client::new();

let response = client.get(download_url).send().await?;

if response.status().is_success() {
let language_path = Path::new(&download_path).parent().unwrap().to_str().unwrap();

fs::create_dir_all(language_path)?;

let mut file = File::create(&download_path)?;

let mut downloaded = 0;
let total_size = response.content_length().unwrap();

let pb = ProgressBar::new(total_size);
pb.set_style(ProgressStyle::with_template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta})")
.unwrap()
.with_key("eta", |state: &ProgressState, w: &mut dyn Write| write!(w, "{:.1}s", state.eta().as_secs_f64()).unwrap())
.progress_chars("#>-"));

while downloaded < total_size {
let new = min(downloaded + 223211, total_size);
downloaded = new;
pb.set_position(new);
thread::sleep(Duration::from_millis(12));
}

pb.finish_with_message("downloaded");

let content = response.bytes().await?;

io::copy(&mut content.as_ref(), &mut file)?;

let unzip_path = format!("{}/{}", language_path, id);

let tar_gz = File::open(&download_path)?;
let tar = GzDecoder::new(tar_gz);
let mut archive = Archive::new(tar);

archive.unpack(&unzip_path)?;

File::create(&formatted_cache_path)?;

fs::copy(&download_path, &formatted_cache_path)?;

fs::remove_file(&download_path)?;

println!("Installed {}! Test it out with: sandbox --new {}", id.bright_green(), id.bright_green())
}
Ok(())
}
}

2 changes: 1 addition & 1 deletion src/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::get_path;
pub async fn open_environment(environment: String) {
let editor = get_editor();

let path = get_path(environment.clone()).await;
let path = get_path(&environment).await;
let environment_path = path.split("/").collect::<Vec<&str>>()[0].to_owned() + "/" + &environment;

let beaches_path = match env::consts::OS {
Expand Down
49 changes: 40 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ mod environment;
mod search;
mod install;
mod uninstall;
mod reinstall;
mod download;
mod cache;
mod new;

use std::error::Error;
Expand All @@ -16,7 +18,9 @@ use args::SandboxArgs;
use search::search;
use install::install_environment;
use uninstall::uninstall_environment;
use reinstall::reinstall_environment;
use new::create_new_environment;
use cache::clear_cache;

use clap::Parser;
use serde_yaml::{Value, Mapping};
Expand All @@ -40,6 +44,14 @@ pub async fn run() {
if !args.uninstall.is_empty() {
uninstall_environment(args.uninstall).await;
}

if !args.reinstall.is_empty() {
reinstall_environment(args.reinstall).await;
}

if args.clearcache {
clear_cache().await;
}
}

pub async fn get_templates_mapping() -> Result<Mapping, Box<dyn Error>> {
Expand Down Expand Up @@ -140,16 +152,9 @@ pub async fn id_is_valid(id: impl Into<String>) -> bool{
pub async fn in_system(id: impl Into<String>) -> bool {
let id = id.into();

let base_path = match env::consts::OS {
"windows" => {
let appdata = std::env::var("appdata").unwrap();
let beaches_path = format!("{}/sandbox/beaches/", appdata);
beaches_path
}
_ => "/usr/share/sandbox/beaches/".to_string(),
};
let base_path = get_beaches_path();

let path = get_path(id.clone()).await;
let path = get_path(&id).await;
let environment_path = path.split("/").collect::<Vec<&str>>()[0].to_owned() + "/" + &id;
let formatted_path = format!("{}{}", base_path, environment_path);

Expand All @@ -161,3 +166,29 @@ pub async fn in_system(id: impl Into<String>) -> bool {
false
}
}

pub fn get_beaches_path() -> String {
match env::consts::OS {
"windows" => {
let appdata = env::var("APPDATA").unwrap();
let beaches_path = format!("{}/sandbox/beaches/", appdata);
beaches_path
}
_ => "/usr/share/sandbox/beaches/".to_string(),
}
}

pub fn get_cache_path() -> String {
match env::consts::OS {
"windows" => {
let appdata = env::var("LOCALAPPDATA").unwrap();
let beaches_path = format!("{}/Temp/sandbox/", appdata);
beaches_path
}
_ => {
let home_path = env::var("HOME").unwrap();
let cache_path = format!("{}/.cache/sandbox/", home_path);
cache_path
}
}
}
22 changes: 22 additions & 0 deletions src/reinstall.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use crate::id_is_valid;
use crate::download::install;
use crate::uninstall::uninstall;

use colored::Colorize;

pub async fn reinstall_environment(id: impl Into<String>) {
let id = id.into();

if id_is_valid(&id).await {
reinstall(&id).await;
} else {
println!("The environment ({}) does {} exist! You can search for an environment with\nsandbox --search {}", id.bright_green(), "not".red(), id.bright_green());
}
}

pub async fn reinstall(id: impl Into<String>) {
let id = id.into();

uninstall(&id).await;
install(&id).await.unwrap();
}
14 changes: 3 additions & 11 deletions src/uninstall.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::env;
use std::io::{stdin, stdout, Write};

use crate::{get_path, id_is_valid, in_system};
use crate::{get_path, get_beaches_path, id_is_valid, in_system};

use colored::Colorize;
use tokio::fs;
Expand All @@ -28,16 +27,9 @@ pub async fn uninstall_environment(environment: impl Into<String>) {
pub async fn uninstall(environment: impl Into<String>) {
let environment = environment.into();

let base_path = match env::consts::OS {
"windows" => {
let appdata = std::env::var("appdata").unwrap();
let beaches_path = format!("{}/sandbox/beaches/", appdata);
beaches_path
}
_ => "/usr/share/sandbox/beaches/".to_string(),
};
let base_path = get_beaches_path();

let path = get_path(environment.clone()).await;
let path = get_path(&environment).await;
let environment_path = path.split("/").collect::<Vec<&str>>()[0].to_owned() + "/" + &environment;

let formatted_path = format!("{}{}", base_path, environment_path);
Expand Down