diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2020-05-28 13:35:24 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-28 13:35:24 -0400 |
commit | dc6c07e3ed12f579889ffce633284aeb45972da6 (patch) | |
tree | ca2a619c2e6ed2360fb7bbb7cdaec89068fc6add | |
parent | 6d9b06619d242ccaae5e735e0f8316950e00c6b5 (diff) |
fix(cli): Handle formatting UTF-8 w/ BOM files (#5881)
-rw-r--r-- | cli/fmt.rs | 54 |
1 files changed, 47 insertions, 7 deletions
diff --git a/cli/fmt.rs b/cli/fmt.rs index 9b6e5975d..c297f042c 100644 --- a/cli/fmt.rs +++ b/cli/fmt.rs @@ -21,6 +21,8 @@ use std::path::PathBuf; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::{Arc, Mutex}; +const BOM_CHAR: char = '\u{FEFF}'; + /// Format JavaScript/TypeScript files. /// /// First argument supports globs, and if it is `None` @@ -66,11 +68,11 @@ async fn check_source_files( run_parallelized(paths, { let not_formatted_files_count = not_formatted_files_count.clone(); move |file_path| { - let file_contents = fs::read_to_string(&file_path)?; - let r = formatter.format_text(&file_path, &file_contents); + let file_text = read_file_contents(&file_path)?.text; + let r = formatter.format_text(&file_path, &file_text); match r { Ok(formatted_text) => { - if formatted_text != file_contents { + if formatted_text != file_text { not_formatted_files_count.fetch_add(1, Ordering::SeqCst); } } @@ -112,12 +114,18 @@ async fn format_source_files( run_parallelized(paths, { let formatted_files_count = formatted_files_count.clone(); move |file_path| { - let file_contents = fs::read_to_string(&file_path)?; - let r = formatter.format_text(&file_path, &file_contents); + let file_contents = read_file_contents(&file_path)?; + let r = formatter.format_text(&file_path, &file_contents.text); match r { Ok(formatted_text) => { - if formatted_text != file_contents { - fs::write(&file_path, formatted_text)?; + if formatted_text != file_contents.text { + write_file_contents( + &file_path, + FileContents { + had_bom: file_contents.had_bom, + text: formatted_text, + }, + )?; formatted_files_count.fetch_add(1, Ordering::SeqCst); let _g = output_lock.lock().unwrap(); println!("{}", file_path.to_string_lossy()); @@ -203,6 +211,38 @@ fn get_config() -> dprint::configuration::Configuration { ConfigurationBuilder::new().deno().build() } +struct FileContents { + text: String, + had_bom: bool, +} + +fn read_file_contents(file_path: &PathBuf) -> Result<FileContents, ErrBox> { + let file_text = fs::read_to_string(&file_path)?; + let had_bom = file_text.starts_with(BOM_CHAR); + let text = if had_bom { + // remove the BOM + String::from(&file_text[BOM_CHAR.len_utf8()..]) + } else { + file_text + }; + + Ok(FileContents { text, had_bom }) +} + +fn write_file_contents( + file_path: &PathBuf, + file_contents: FileContents, +) -> Result<(), ErrBox> { + let file_text = if file_contents.had_bom { + // add back the BOM + format!("{}{}", BOM_CHAR, file_contents.text) + } else { + file_contents.text + }; + + Ok(fs::write(file_path, file_text)?) +} + async fn run_parallelized<F>( file_paths: Vec<PathBuf>, f: F, |