From cf7c9762b12baef9e82c4fcb4a8946d6d1ac05f0 Mon Sep 17 00:00:00 2001 From: hlafaille Date: Tue, 12 Mar 2024 15:30:13 -0400 Subject: [PATCH] cleaning up garbage --- src/backend/context.rs | 118 +++++++++++++++++++++++++++++++++--- src/backend/mod.rs | 2 +- src/backend/project.rs | 115 +++++++++-------------------------- src/backend/toolchain.rs | 9 +-- src/frontend/command.rs | 17 +++--- src/frontend/mod.rs | 2 +- src/frontend/service/mod.rs | 49 ++++++++++----- src/frontend/terminal.rs | 7 ++- src/main.rs | 13 ++-- src/util/directory.rs | 6 +- src/util/mod.rs | 3 +- src/util/pathutil.rs | 12 ++++ 12 files changed, 210 insertions(+), 143 deletions(-) create mode 100644 src/util/pathutil.rs diff --git a/src/backend/context.rs b/src/backend/context.rs index 6239b19..c0dbd50 100644 --- a/src/backend/context.rs +++ b/src/backend/context.rs @@ -1,19 +1,121 @@ +use std::{cell::Cell, env}; + use crate::backend::project::Config; use super::project::get_config_from_fs; -/** - * Represents the currently loaded project - */ +/// Represents the context of the currently loaded project. pub struct ProjectContext { + /// Project config (espresso.toml) pub config: Config, + /// Absolute paths (with suffixes known at compile time) that're relavent to this project (ex: path to src) + pub absolute_paths: AbsoltuePaths, + /// Absolute paths (with suffixes NOT known at compile time) that're relavent to this project (ex: path to base package) + pub dynamic_absolute_paths: DynamicAbsolutePaths, + /// If we're running in debug mode (ESPRESSO_DEBUG=1) + pub debug_mode: bool, +} + +/// Contains absolute paths to critical resources within the currently loaded project. +pub struct AbsoltuePaths { + /// Path to the currently loaded projects directory. Should be the current working directory. + pub project: String, + /// Path to the src/ directory within the currently loaded project. + pub source: String, + /// Path to the config file within the currently loaded project. + pub config: String, +} + +/// Contains absolute paths to critical resources within the currently loaded project. Determined at runtime. +pub struct DynamicAbsolutePaths { + /// Path to the base package. Should be {source}/package/path/here. The Main.java file will live here. + pub base_package: Cell, +} + +/// Get if debug mode is active. You can enable debug mode by setting the `ESPRESSO_DEBUG` +/// environment variable to `1`. +/// +/// # Returns +/// +/// `true` if `ESPRESSO_DEBUG=1`, `false` if `ESPRESSO_DEBUG=0` or not set +pub fn get_debug_mode() -> bool { + match env::var("ESPRESSO_DEBUG") { + Ok(v) => { + if v == "1" { + return true; + } else if v == "0" { + return false; + } else { + return false; + } + } + Err(_) => return false, + }; } -/** - * Get the Project Context - */ +/// Get an AbsolutePaths struct +/// +/// # Arguments +/// +/// * `config`: Reference to a Config +/// * `debug_mode`: Reference to a bool if we're in debug mode +/// +/// # Returns +/// +/// AbsolutePaths +fn get_absolute_paths(debug_mode: &bool) -> AbsoltuePaths { + let cwd = env::current_dir() + .expect("Failed to read the current working directory; are you in a shell?") + .to_string_lossy() + .into_owned(); + AbsoltuePaths { + project: cwd.clone(), + source: cwd.clone() + "/src", + config: cwd.clone() + "/espresso.toml", + } +} + +/// Get a DynamicAbsolutePaths struct. +/// +/// # Arguments +/// * `ap`: Reference to an `AbsolutePaths` struct. Used to get the `src/` directory. +/// * `config`: Reference to a `Config` struct. used to get the current `base_package`. +/// * `debug_mode`: Reference to a bool if we're in debug mode +/// +/// # Returns +/// +/// DynamicAbsolutePaths +fn get_dynamic_absolute_paths( + ap: &AbsoltuePaths, + config: &Config, + debug_mode: &bool, +) -> DynamicAbsolutePaths { + let base_package = Cell::new( + ap.source.clone() + + config + .project + .base_package + .clone() + .replace(".", "/") + .as_str(), + ); + DynamicAbsolutePaths { base_package } +} + +/// Get context about the currently loaded project. +/// +/// # Returns +/// +/// ProjectContext pub fn get_project_context() -> ProjectContext { + let debug_mode = get_debug_mode(); + let absolute_paths = get_absolute_paths(&debug_mode); + let config = get_config_from_fs(&absolute_paths); + let dynamic_absolute_paths = get_dynamic_absolute_paths(&absolute_paths, &config, &debug_mode); ProjectContext { - config: get_config_from_fs() + config, + absolute_paths, + debug_mode, + dynamic_absolute_paths, } -} \ No newline at end of file +} diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 84b766f..71b0d95 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -1,3 +1,3 @@ +pub mod context; pub mod project; pub mod toolchain; -pub mod context; \ No newline at end of file diff --git a/src/backend/project.rs b/src/backend/project.rs index 41e0691..19edc74 100644 --- a/src/backend/project.rs +++ b/src/backend/project.rs @@ -1,6 +1,13 @@ -use std::{collections::HashMap, env, fs::{self, create_dir_all}, path::Path}; +use crate::util::pathutil; + +use super::context::{AbsoltuePaths, DynamicAbsolutePaths, ProjectContext}; use serde::{Deserialize, Serialize}; -use super::context::ProjectContext; +use std::{ + collections::HashMap, + env, + fs::{self, create_dir_all}, + path::Path, +}; #[derive(Deserialize, Serialize, Debug)] pub struct Config { @@ -21,70 +28,22 @@ pub struct Toolchain { pub path: String, } -/** - * Get if ESPRESSO_DEBUG=1 - */ -pub fn get_debug_mode() -> bool { - match env::var("ESPRESSO_DEBUG") { - Ok(v) => { - if v == "1" { - return true - } else if v == "0" { - return false - } else { - return false - } - } - Err(_) => return false, - }; -} - -/** - * Get the config path. Note, this value changes if ESPRESSO_DEBUG=1 - */ -pub fn get_config_path() -> String { - let debug_mode = get_debug_mode(); - if debug_mode { - "espresso_debug/espresso.toml".to_string() - } else { - "espresso.toml".to_string() - } -} - -pub fn get_absolute_project_path() -> String { - let debug_mode = get_debug_mode(); - let current_dir = env::current_dir().unwrap().to_string_lossy().into_owned(); - if debug_mode { - current_dir + "/espresso_debug" - } else { - current_dir - } -} - -/** - * Get the source path. Note, this value is prefixed with `espresso_debug` if ESPRESSO_DEBUG=1 - */ -pub fn get_source_path() -> String { - (get_absolute_project_path() + "/src/java").to_string() -} - /** * Ensure development directory exists */ -pub fn ensure_debug_directory_exists_if_debug(){ - if !get_debug_mode() { - return; - } - if !Path::exists(Path::new("espresso_debug")) { - create_dir_all("espresso_debug").expect("Failed to ensure debug directory exists"); +pub fn ensure_debug_directory_exists_if_debug(p_ctx: &ProjectContext) { + if p_ctx.debug_mode { + if !Path::exists(Path::new("espresso_debug")) { + create_dir_all("espresso_debug").expect("Failed to ensure debug directory exists"); + } } } /** * Load the project at the current working directory */ -pub fn get_config_from_fs() -> Config { - let contents = fs::read_to_string(get_config_path()).expect("Unable to read conig file"); +pub fn get_config_from_fs(ap: &AbsoltuePaths) -> Config { + let contents = fs::read_to_string(ap.config).expect("Unable to read conig file"); toml::from_str(&contents).unwrap() } @@ -92,9 +51,9 @@ pub fn get_config_from_fs() -> Config { * If a project exists. A project is deemed existing if it has a source directory * and a config file. */ -pub fn does_exist() -> bool { - let source_exists = does_source_exist(); - let config_exists = does_config_exist(); +pub fn does_exist(ap: &AbsoltuePaths) -> bool { + let source_exists = pathutil::does_path_exist(&ap.source); + let config_exists = pathutil::does_path_exist(&ap.config); // Return false if either source or config does not exist if !source_exists || !config_exists { @@ -105,32 +64,13 @@ pub fn does_exist() -> bool { true } -/** - * If the source path (ex: src) exists - */ -pub fn does_source_exist() -> bool { - Path::exists(Path::new(get_source_path().as_str())) -} - -/** - * Checks if the config exists - */ -pub fn does_config_exist() -> bool { - Path::exists(Path::new(get_config_path().as_str())) -} - -/** - * Get the base package path. This value is the `location of src + base_package` - */ -pub fn get_full_base_package_path(p_ctx: &ProjectContext) -> String{ - format!("{}/{}", get_source_path(), p_ctx.config.project.base_package.replace(".", "/")) -} - /** * Initialize the source tree */ pub fn initialize_source_tree(p_ctx: &ProjectContext) { - std::fs::create_dir_all(get_full_base_package_path(p_ctx)).expect("failed to create main package directories in file system"); + let base_package_path = p_ctx.dynamic_absolute_paths.base_package.take(); + std::fs::create_dir_all(base_package_path) + .expect("failed to create main package directories in file system"); // create the Main.java file (textwrap doesn't work????) let base_java_content = r#"package ${BASE_PACKAGE}; @@ -140,9 +80,10 @@ public class Main { public static void main(String[] args) { System.out.println("Hello, world!"); } -}"#.replace("${BASE_PACKAGE}", &p_ctx.config.project.base_package); - - std::fs::write(get_full_base_package_path(p_ctx) + "/Main.java", base_java_content); +}"# + .replace("${BASE_PACKAGE}", &p_ctx.config.project.base_package); + + std::fs::write(base_package_path + "/Main.java", base_java_content); } fn process_input(x: String, default: String) -> String { @@ -156,7 +97,7 @@ fn process_input(x: String, default: String) -> String { /** * Initialize a config */ -pub fn initialize_config(name: String, base_package: String) { +pub fn initialize_config(name: String, base_package: String, ap: &AbsoltuePaths) { // process the name // populate a base_config struct let base_config = Config { @@ -173,5 +114,5 @@ pub fn initialize_config(name: String, base_package: String) { // write it to a toml string, then write it to the config file let toml_string = toml::to_string(&base_config).expect("Failed to serialize struct"); - fs::write(get_config_path(), toml_string).expect("Failed to write config file") + fs::write(ap.config, toml_string).expect("Failed to write config file") } diff --git a/src/backend/toolchain.rs b/src/backend/toolchain.rs index 89b8aa9..27b414a 100644 --- a/src/backend/toolchain.rs +++ b/src/backend/toolchain.rs @@ -4,18 +4,13 @@ use crate::{ }; use std::{ borrow::Cow, - env, - fmt::format, - fs, io, path, + env, fs, io, path, process::{Command, ExitStatus}, vec, }; use walkdir::WalkDir; -use super::{ - context::ProjectContext, - project::{self, get_absolute_project_path, get_full_base_package_path, Project}, -}; +use super::context::ProjectContext; /** * Represents the context of the current Java toolchain diff --git a/src/frontend/command.rs b/src/frontend/command.rs index e62de8b..28f7f8f 100644 --- a/src/frontend/command.rs +++ b/src/frontend/command.rs @@ -1,21 +1,20 @@ - -use clap::{Command}; +use clap::Command; use once_cell::sync::Lazy; pub static BUILD_CMD: Lazy = Lazy::new(|| { Command::new("build") - .about("Build your Java project into a standalone .jar") - .alias("b") + .about("Build your Java project into a standalone .jar") + .alias("b") }); pub static INIT_CMD: Lazy = Lazy::new(|| { Command::new("init") - .about("Initialize a new Espresso project") - .alias("i") + .about("Initialize a new Espresso project") + .alias("i") }); pub static RUN_CMD: Lazy = Lazy::new(|| { Command::new("run") - .about("Build & run your Java project") - .alias("i") -}); \ No newline at end of file + .about("Build & run your Java project") + .alias("i") +}); diff --git a/src/frontend/mod.rs b/src/frontend/mod.rs index 3170a87..69c60c7 100644 --- a/src/frontend/mod.rs +++ b/src/frontend/mod.rs @@ -1,3 +1,3 @@ pub mod command; pub mod service; -pub mod terminal; \ No newline at end of file +pub mod terminal; diff --git a/src/frontend/service/mod.rs b/src/frontend/service/mod.rs index 5e5854d..a5c0307 100644 --- a/src/frontend/service/mod.rs +++ b/src/frontend/service/mod.rs @@ -2,7 +2,9 @@ use std::io; use crate::backend; use crate::backend::context::{get_project_context, ProjectContext}; -use crate::backend::toolchain::{compile_project, get_toolchain_context, run_jar, ToolchainContext}; +use crate::backend::toolchain::{ + compile_project, get_toolchain_context, run_jar, ToolchainContext, +}; use crate::frontend::terminal::{print_err, print_sameline}; use super::terminal::print_general; @@ -15,14 +17,18 @@ pub fn run(override_p_ctx: Option, override_tc_ctx: Option p_ctx = v, - None => p_ctx = get_project_context() + None => p_ctx = get_project_context(), } // handle an override toolchain context let mut tc_ctx: ToolchainContext; match override_tc_ctx { - Some(v) => { tc_ctx = v; }, - None => { tc_ctx = get_toolchain_context(&p_ctx); } + Some(v) => { + tc_ctx = v; + } + None => { + tc_ctx = get_toolchain_context(&p_ctx); + } } // build our jar @@ -36,28 +42,38 @@ pub fn run(override_p_ctx: Option, override_tc_ctx: Option, override_tc_ctx: Option) -> (ProjectContext, ToolchainContext) { +pub fn build( + override_p_ctx: Option, + override_tc_ctx: Option, +) -> (ProjectContext, ToolchainContext) { // handle an override project context let p_ctx: ProjectContext; match override_p_ctx { Some(v) => p_ctx = v, - None => p_ctx = get_project_context() + None => p_ctx = get_project_context(), } // handle an override toolchain context let tc_ctx: ToolchainContext; match override_tc_ctx { - Some(v) => { tc_ctx = v; }, - None => { tc_ctx = get_toolchain_context(&p_ctx); } + Some(v) => { + tc_ctx = v; + } + None => { + tc_ctx = get_toolchain_context(&p_ctx); + } } // walk our src directory, find source files let java_files = backend::toolchain::get_java_source_files(&p_ctx).unwrap(); print_general( - format!("Discovered {} source file(s) in base package '{}'", - java_files.len(), - &p_ctx.config.project.base_package, - ).as_str()); + format!( + "Discovered {} source file(s) in base package '{}'", + java_files.len(), + &p_ctx.config.project.base_package, + ) + .as_str(), + ); // compile the project to class files print_general("Compiling"); @@ -66,12 +82,11 @@ pub fn build(override_p_ctx: Option, override_tc_ctx: Option, override_tc_ctx: Option { frontend::service::build(None, None); @@ -31,8 +30,6 @@ fn main() { Some("run") => { frontend::service::run(None, None); } - _ => { - print_err("Unknown subcommand") - } + _ => print_err("Unknown subcommand"), } } diff --git a/src/util/directory.rs b/src/util/directory.rs index fbba1d5..27c51a0 100644 --- a/src/util/directory.rs +++ b/src/util/directory.rs @@ -14,9 +14,9 @@ pub fn read_files_recursively(path: String) -> Result, Error> { } else { files.push(path); } - }, - Err(_) => unimplemented!("error case on reading files recursively") + } + Err(_) => unimplemented!("error case on reading files recursively"), } } return Ok(files); -} \ No newline at end of file +} diff --git a/src/util/mod.rs b/src/util/mod.rs index a0932dd..ed7f0cc 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -1 +1,2 @@ -pub mod directory; \ No newline at end of file +pub mod directory; +pub mod pathutil; diff --git a/src/util/pathutil.rs b/src/util/pathutil.rs new file mode 100644 index 0000000..6323e76 --- /dev/null +++ b/src/util/pathutil.rs @@ -0,0 +1,12 @@ +use std::path::Path; + +/// If a path on the filesystem exists +/// +/// # Arguments +/// * `path`: Reference to a `String` containing the path to the file you want to check for existence. +/// +/// # Returns +/// `true` if exists, `false` if not. +pub fn does_path_exist(path: &String) -> bool { + Path::exists(Path::new(path)) +}