diff --git a/bin/src/commands/build.rs b/bin/src/commands/build.rs index 4128e4ca..27ffed80 100644 --- a/bin/src/commands/build.rs +++ b/bin/src/commands/build.rs @@ -4,7 +4,7 @@ use crate::{ context::{self, Context}, error::Error, executor::Executor, - modules::{pbo::Collapse, Binarize, Files, Hooks, Rapifier, SQFCompiler}, + modules::{bom::BOMCheck, pbo::Collapse, Binarize, Files, Hooks, Rapifier, SQFCompiler}, report::Report, }; @@ -96,6 +96,7 @@ pub fn executor(ctx: Context, matches: &ArgMatches) -> Executor { executor.collapse(Collapse::No); + executor.add_module(Box::::default()); executor.add_module(Box::::default()); if matches.get_one::("no-rap") != Some(&true) { executor.add_module(Box::::default()); diff --git a/bin/src/commands/check.rs b/bin/src/commands/check.rs index 9470ef7e..8d7913e9 100644 --- a/bin/src/commands/check.rs +++ b/bin/src/commands/check.rs @@ -4,7 +4,7 @@ use crate::{ context::Context, error::Error, executor::Executor, - modules::{pbo::Collapse, Binarize, Hooks, Rapifier, SQFCompiler}, + modules::{bom::BOMCheck, pbo::Collapse, Binarize, Hooks, Rapifier, SQFCompiler}, report::Report, }; @@ -28,6 +28,7 @@ pub fn execute() -> Result { executor.collapse(Collapse::Yes); + executor.add_module(Box::::default()); executor.add_module(Box::::default()); executor.add_module(Box::::default()); executor.add_module(Box::::default()); diff --git a/bin/src/commands/dev.rs b/bin/src/commands/dev.rs index d3ac8b15..30777b15 100644 --- a/bin/src/commands/dev.rs +++ b/bin/src/commands/dev.rs @@ -5,7 +5,9 @@ use crate::{ context::Context, error::Error, executor::Executor, - modules::{pbo::Collapse, Binarize, FilePatching, Files, Hooks, Rapifier, SQFCompiler}, + modules::{ + bom::BOMCheck, pbo::Collapse, Binarize, FilePatching, Files, Hooks, Rapifier, SQFCompiler, + }, report::Report, }; @@ -136,6 +138,7 @@ pub fn context( executor.collapse(Collapse::Yes); + executor.add_module(Box::::default()); executor.add_module(Box::::default()); if rapify && matches.get_one::("no-rap") != Some(&true) { executor.add_module(Box::::default()); diff --git a/bin/src/modules/bom.rs b/bin/src/modules/bom.rs new file mode 100644 index 00000000..80ac1f87 --- /dev/null +++ b/bin/src/modules/bom.rs @@ -0,0 +1,75 @@ +use std::{io::Read, path::PathBuf, sync::Arc}; + +use hemtt_workspace::reporting::Code; + +use crate::{context::Context, report::Report}; + +use super::Module; + +#[derive(Default)] +pub struct BOMCheck {} + +impl Module for BOMCheck { + fn name(&self) -> &'static str { + "BOM Check" + } + + fn check(&self, ctx: &Context) -> Result { + fn files_to_check(root: &PathBuf) -> Vec { + const IGNORED_EXTENSIONS: [&str; 4] = ["p3d", "rtm", "bin", "paa"]; + walkdir::WalkDir::new(root) + .into_iter() + .filter_map(std::result::Result::ok) + .filter(|e| e.file_type().is_file()) + .filter(|e| !e.path().display().to_string().contains(".hemttout")) + .filter(|e| { + e.path().extension().map_or(false, |e| { + !IGNORED_EXTENSIONS.contains(&e.to_str().unwrap_or_default()) + }) + }) + .map(|e| e.path().to_path_buf()) + .collect::>() + } + let mut report = Report::new(); + for folder in ["addons", "optionals"] { + let folder = ctx.project_folder().join(folder); + if !folder.exists() { + continue; + } + let files = files_to_check(&folder); + for path in files { + let mut buffer = [0; 3]; + let mut file = std::fs::File::open(&path)?; + if file.read_exact(&mut buffer).is_err() { + continue; + } + if buffer == [0xEF, 0xBB, 0xBF] { + report.push(Arc::new(BOMError { + file: { + path.display() + .to_string() + .strip_prefix(&ctx.project_folder().display().to_string()) + .unwrap_or_default() + .to_string() + }, + })); + } + } + } + Ok(report) + } +} + +struct BOMError { + file: String, +} + +impl Code for BOMError { + fn ident(&self) -> &'static str { + "BOM" + } + + fn message(&self) -> String { + format!("File `{}` has a BOM marker", self.file) + } +} diff --git a/bin/src/modules/mod.rs b/bin/src/modules/mod.rs index fea36b80..5da54869 100644 --- a/bin/src/modules/mod.rs +++ b/bin/src/modules/mod.rs @@ -4,6 +4,7 @@ use crate::{context::Context, error::Error, report::Report}; pub mod asc; pub mod archive; +pub mod bom; pub mod hook; pub mod pbo; diff --git a/bin/tests/alpha/.hemtt/project.toml b/bin/tests/alpha/.hemtt/project.toml index 30d380de..5361f6d8 100644 --- a/bin/tests/alpha/.hemtt/project.toml +++ b/bin/tests/alpha/.hemtt/project.toml @@ -11,7 +11,7 @@ git_hash = 0 [asc] enabled = true -[hemtt.launch] +[hemtt.launch.default] dlc = [ "ws" ] diff --git a/libs/workspace/src/reporting/mod.rs b/libs/workspace/src/reporting/mod.rs index cb1766a3..81b24b4b 100644 --- a/libs/workspace/src/reporting/mod.rs +++ b/libs/workspace/src/reporting/mod.rs @@ -71,13 +71,13 @@ pub trait Code: Send + Sync { /// A diagnostic for the LSP / terminal fn diagnostic(&self) -> Option { - let token = self.token()?; - let mut diag = Diagnostic::new(self.ident(), self.message()) - .with_label( + let mut diag = Diagnostic::new(self.ident(), self.message()).set_severity(self.severity()); + if let Some(token) = self.token() { + diag = diag.with_label( Label::primary(token.position().path().clone(), token.position().span()) .with_message(self.label_message()), - ) - .set_severity(self.severity()); + ); + } if let Some(note) = self.note() { diag = diag.with_note(note); }