diff --git a/Cargo.lock b/Cargo.lock index 9902461..e182552 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,6 +72,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "anyhow" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" + [[package]] name = "arrayref" version = "0.3.7" @@ -713,6 +719,7 @@ name = "rewatch" version = "1.0.9" dependencies = [ "ahash", + "anyhow", "blake3", "clap", "clap-verbosity-flag", diff --git a/Cargo.toml b/Cargo.toml index 5195fec..7266bb6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ clap = { version = "4.3.17", features = ["derive"] } sysinfo = "0.29.10" ctrlc = "3.4.4" clap-verbosity-flag = "2.2.2" +anyhow = "1.0.93" [profile.release] diff --git a/src/build/build_types.rs b/src/build/build_types.rs index 04f7132..95e9039 100644 --- a/src/build/build_types.rs +++ b/src/build/build_types.rs @@ -1,6 +1,6 @@ use crate::build::packages::{Namespace, Package}; use ahash::{AHashMap, AHashSet}; -use std::time::SystemTime; +use std::{fmt::Display, time::SystemTime}; #[derive(Debug, Clone, PartialEq)] pub enum ParseState { @@ -52,6 +52,15 @@ pub enum SourceType { MlMap(MlMap), } +impl Display for SourceType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + SourceType::SourceFile(_) => write!(f, "SourceFile"), + SourceType::MlMap(_) => write!(f, "MlMap"), + } + } +} + #[derive(Debug, Clone)] pub struct Module { pub source_type: SourceType, diff --git a/src/build/compile.rs b/src/build/compile.rs index 408d355..b08d0b8 100644 --- a/src/build/compile.rs +++ b/src/build/compile.rs @@ -8,6 +8,7 @@ use super::packages; use crate::config; use crate::helpers; use ahash::{AHashMap, AHashSet}; +use anyhow::{anyhow, Result}; use console::style; use log::{debug, log_enabled, trace, Level::Info}; use rayon::prelude::*; @@ -225,106 +226,100 @@ pub fn compile( } }) }) - .collect::<Vec< - Option<( - String, - Result<Option<String>, String>, - Option<Result<Option<String>, String>>, - bool, - bool, - )>, - >>() + .collect::<Vec<_>>() .iter() - .for_each(|result| if let Some((module_name, result, interface_result, is_clean, is_compiled)) = result { - in_progress_modules.remove(module_name); + .for_each(|result| { + if let Some((module_name, result, interface_result, is_clean, is_compiled)) = result { + in_progress_modules.remove(module_name); - if *is_compiled { - num_compiled_modules += 1; - } + if *is_compiled { + num_compiled_modules += 1; + } - files_current_loop_count += 1; - compiled_modules.insert(module_name.to_string()); + files_current_loop_count += 1; + compiled_modules.insert(module_name.to_string()); - if *is_clean { - // actually add it to a list of clean modules - clean_modules.insert(module_name.to_string()); - } + if *is_clean { + // actually add it to a list of clean modules + clean_modules.insert(module_name.to_string()); + } - let module_dependents = build_state.get_module(module_name).unwrap().dependents.clone(); + let module_dependents = build_state.get_module(module_name).unwrap().dependents.clone(); - // if not clean -- compile modules that depend on this module - for dep in module_dependents.iter() { - // mark the reverse dep as dirty when the source is not clean - if !*is_clean { - let dep_module = build_state.modules.get_mut(dep).unwrap(); + // if not clean -- compile modules that depend on this module + for dep in module_dependents.iter() { // mark the reverse dep as dirty when the source is not clean - dep_module.compile_dirty = true; - } - if !compiled_modules.contains(dep) { - in_progress_modules.insert(dep.to_string()); + if !*is_clean { + let dep_module = build_state.modules.get_mut(dep).unwrap(); + // mark the reverse dep as dirty when the source is not clean + dep_module.compile_dirty = true; + } + if !compiled_modules.contains(dep) { + in_progress_modules.insert(dep.to_string()); + } } - } - let module = build_state.modules.get_mut(module_name).unwrap(); - let package = build_state - .packages - .get(&module.package_name) - .expect("Package not found"); - match module.source_type { - SourceType::MlMap(ref mut mlmap) => { - module.compile_dirty = false; - mlmap.parse_dirty = false; - } - SourceType::SourceFile(ref mut source_file) => { - match result { - Ok(Some(err)) => { - source_file.implementation.compile_state = CompileState::Warning; - logs::append(package, err); - compile_warnings.push_str(err); - } - Ok(None) => { - source_file.implementation.compile_state = CompileState::Success; - } - Err(err) => { - source_file.implementation.compile_state = CompileState::Error; - logs::append(package, err); - compile_errors.push_str(err); - } - }; - match interface_result { - Some(Ok(Some(err))) => { - source_file.interface.as_mut().unwrap().compile_state = - CompileState::Warning; - logs::append(package, err); - compile_warnings.push_str(err); - } - Some(Ok(None)) => { - if let Some(interface) = source_file.interface.as_mut() { - interface.compile_state = CompileState::Success; + let module = build_state.modules.get_mut(module_name).unwrap(); + let package = build_state + .packages + .get(&module.package_name) + .expect("Package not found"); + match module.source_type { + SourceType::MlMap(ref mut mlmap) => { + module.compile_dirty = false; + mlmap.parse_dirty = false; + } + SourceType::SourceFile(ref mut source_file) => { + match result { + Ok(Some(err)) => { + source_file.implementation.compile_state = CompileState::Warning; + logs::append(package, err); + compile_warnings.push_str(err); + } + Ok(None) => { + source_file.implementation.compile_state = CompileState::Success; + } + Err(err) => { + source_file.implementation.compile_state = CompileState::Error; + logs::append(package, &err.to_string()); + compile_errors.push_str(&err.to_string()); + } + }; + match interface_result { + Some(Ok(Some(err))) => { + source_file.interface.as_mut().unwrap().compile_state = + CompileState::Warning; + logs::append(package, &err.to_string()); + compile_warnings.push_str(&err.to_string()); + } + Some(Ok(None)) => { + if let Some(interface) = source_file.interface.as_mut() { + interface.compile_state = CompileState::Success; + } } - } - Some(Err(err)) => { - source_file.interface.as_mut().unwrap().compile_state = - CompileState::Error; - logs::append(package, err); - compile_errors.push_str(err); - } - _ => (), - }; - match (result, interface_result) { - // successfull compilation - (Ok(None), Some(Ok(None))) | (Ok(None), None) => { - module.compile_dirty = false; - module.last_compiled_cmi = Some(SystemTime::now()); - module.last_compiled_cmt = Some(SystemTime::now()); - } - // some error or warning - (Err(_), _) - | (_, Some(Err(_))) - | (Ok(Some(_)), _) - | (_, Some(Ok(Some(_)))) => { - module.compile_dirty = true; + Some(Err(err)) => { + source_file.interface.as_mut().unwrap().compile_state = + CompileState::Error; + logs::append(package, &err.to_string()); + compile_errors.push_str(&err.to_string()); + } + _ => (), + }; + match (result, interface_result) { + // successfull compilation + (Ok(None), Some(Ok(None))) | (Ok(None), None) => { + module.compile_dirty = false; + module.last_compiled_cmi = Some(SystemTime::now()); + module.last_compiled_cmt = Some(SystemTime::now()); + } + // some error or warning + (Err(_), _) + | (_, Some(Err(_))) + | (Ok(Some(_)), _) + | (_, Some(Ok(Some(_)))) => { + module.compile_dirty = true; + } } } } @@ -523,12 +518,16 @@ fn compile_file( packages: &AHashMap<String, packages::Package>, project_root: &str, workspace_root: &Option<String>, -) -> Result<Option<String>, String> { +) -> Result<Option<String>> { let build_path_abs = package.get_build_path(); - let implementation_file_path = match module.source_type { - SourceType::SourceFile(ref source_file) => &source_file.implementation.path, - _ => panic!("Not a source file"), - }; + let implementation_file_path = match &module.source_type { + SourceType::SourceFile(ref source_file) => Ok(&source_file.implementation.path), + sourcetype => Err(anyhow!( + "Tried to compile a file that is not a source file ({}). Path to AST: {}. ", + sourcetype, + ast_path + )), + }?; let module_name = helpers::file_path_to_module_name(implementation_file_path, &package.namespace); let has_interface = module.get_interface().is_some(); let to_mjs_args = compiler_args( @@ -553,9 +552,9 @@ fn compile_file( Ok(x) if !x.status.success() => { let stderr = String::from_utf8_lossy(&x.stderr); let stdout = String::from_utf8_lossy(&x.stdout); - Err(stderr.to_string() + &stdout) + Err(anyhow!(stderr.to_string() + &stdout)) } - Err(e) => Err(format!("ERROR, {}, {:?}", e, ast_path)), + Err(e) => Err(anyhow!("Could not compile file. Error: {}. Path to AST: {:?}", e, ast_path)), Ok(x) => { let err = std::str::from_utf8(&x.stderr) .expect("stdout should be non-null")