From 591419611e87cf8dfa6bc839131b32bb3fb78b5d Mon Sep 17 00:00:00 2001 From: Kenneth Loeffler Date: Wed, 14 Feb 2024 10:18:46 -0800 Subject: [PATCH] Backport #854 to Rojo 7.4 (Lua LF normalization) (#857) --- CHANGELOG.md | 2 ++ crates/memofs/CHANGELOG.md | 2 ++ crates/memofs/src/lib.rs | 47 +++++++++++++++++++++++++++++++++- src/snapshot_middleware/lua.rs | 9 +++---- src/snapshot_middleware/txt.rs | 10 +++----- 5 files changed, 56 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 902b12e3..34b4b08d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Rojo Changelog ## Unreleased Changes +* Rojo now converts any line endings to LF, preventing spurious diffs when syncing Lua files on Windows ([#854]) * Fixed Rojo plugin failing to connect when project contains certain unreadable properties ([#848]) * Fixed various cases where patch visualizer would not display sync failures ([#845], [#844]) * Fixed http error handling so Rojo can be used in Github Codespaces ([#847]) @@ -9,6 +10,7 @@ [#845]: https://github.com/rojo-rbx/rojo/pull/845 [#844]: https://github.com/rojo-rbx/rojo/pull/844 [#847]: https://github.com/rojo-rbx/rojo/pull/847 +[#854]: https://github.com/rojo-rbx/rojo/pull/854 ## [7.4.0] - January 16, 2024 * Improved the visualization for array properties like Tags ([#829]) diff --git a/crates/memofs/CHANGELOG.md b/crates/memofs/CHANGELOG.md index c9961d0e..d678f8c9 100644 --- a/crates/memofs/CHANGELOG.md +++ b/crates/memofs/CHANGELOG.md @@ -2,8 +2,10 @@ ## Unreleased Changes * Changed `StdBackend` file watching component to use minimal recursive watches. [#830] +* Added `Vfs::read_to_string` and `Vfs::read_to_string_lf_normalized` [#854] [#830]: https://github.com/rojo-rbx/rojo/pull/830 +[#854]: https://github.com/rojo-rbx/rojo/pull/854 ## 0.2.0 (2021-08-23) * Updated to `crossbeam-channel` 0.5.1. diff --git a/crates/memofs/src/lib.rs b/crates/memofs/src/lib.rs index 744ca60f..6d41c853 100644 --- a/crates/memofs/src/lib.rs +++ b/crates/memofs/src/lib.rs @@ -22,9 +22,9 @@ mod noop_backend; mod snapshot; mod std_backend; -use std::io; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex, MutexGuard}; +use std::{io, str}; pub use in_memory_fs::InMemoryFs; pub use noop_backend::NoopBackend; @@ -155,6 +155,24 @@ impl VfsInner { Ok(Arc::new(contents)) } + fn read_to_string>(&mut self, path: P) -> io::Result> { + let path = path.as_ref(); + let contents = self.backend.read(path)?; + + if self.watch_enabled { + self.backend.watch(path)?; + } + + let contents_str = str::from_utf8(&contents).map_err(|_| { + io::Error::new( + io::ErrorKind::InvalidData, + format!("File was not valid UTF-8: {}", path.display()), + ) + })?; + + Ok(Arc::new(contents_str.into())) + } + fn write, C: AsRef<[u8]>>(&mut self, path: P, contents: C) -> io::Result<()> { let path = path.as_ref(); let contents = contents.as_ref(); @@ -258,6 +276,33 @@ impl Vfs { self.inner.lock().unwrap().read(path) } + /// Read a file from the VFS (or from the underlying backend if it isn't + /// resident) into a string. + /// + /// Roughly equivalent to [`std::fs::read_to_string`][std::fs::read_to_string]. + /// + /// [std::fs::read_to_string]: https://doc.rust-lang.org/stable/std/fs/fn.read_to_string.html + #[inline] + pub fn read_to_string>(&self, path: P) -> io::Result> { + let path = path.as_ref(); + self.inner.lock().unwrap().read_to_string(path) + } + + /// Read a file from the VFS (or the underlying backend if it isn't + /// resident) into a string, and normalize its line endings to LF. + /// + /// Roughly equivalent to [`std::fs::read_to_string`][std::fs::read_to_string], but also performs + /// line ending normalization. + /// + /// [std::fs::read_to_string]: https://doc.rust-lang.org/stable/std/fs/fn.read_to_string.html + #[inline] + pub fn read_to_string_lf_normalized>(&self, path: P) -> io::Result> { + let path = path.as_ref(); + let contents = self.inner.lock().unwrap().read_to_string(path)?; + + Ok(contents.lines().collect::>().join("\n").into()) + } + /// Write a file to the VFS and the underlying backend. /// /// Roughly equivalent to [`std::fs::write`][std::fs::write]. diff --git a/src/snapshot_middleware/lua.rs b/src/snapshot_middleware/lua.rs index 1307b066..baaf4476 100644 --- a/src/snapshot_middleware/lua.rs +++ b/src/snapshot_middleware/lua.rs @@ -1,6 +1,5 @@ -use std::{collections::HashMap, path::Path, str}; +use std::{collections::HashMap, path::Path}; -use anyhow::Context; use memofs::{IoResultExt, Vfs}; use rbx_dom_weak::types::Enum; @@ -58,10 +57,8 @@ pub fn snapshot_lua( (_, ScriptType::Module) => ("ModuleScript", None), }; - let contents = vfs.read(path)?; - let contents_str = str::from_utf8(&contents) - .with_context(|| format!("File was not valid UTF-8: {}", path.display()))? - .to_owned(); + let contents = vfs.read_to_string_lf_normalized(path)?; + let contents_str = contents.as_str(); let mut properties = HashMap::with_capacity(2); properties.insert("Source".to_owned(), contents_str.into()); diff --git a/src/snapshot_middleware/txt.rs b/src/snapshot_middleware/txt.rs index 13d5b990..8a44e1f8 100644 --- a/src/snapshot_middleware/txt.rs +++ b/src/snapshot_middleware/txt.rs @@ -1,6 +1,5 @@ -use std::{path::Path, str}; +use std::path::Path; -use anyhow::Context; use maplit::hashmap; use memofs::{IoResultExt, Vfs}; @@ -14,11 +13,8 @@ pub fn snapshot_txt( path: &Path, ) -> anyhow::Result> { let name = path.file_name_trim_end(".txt")?; - - let contents = vfs.read(path)?; - let contents_str = str::from_utf8(&contents) - .with_context(|| format!("File was not valid UTF-8: {}", path.display()))? - .to_owned(); + let contents = vfs.read_to_string(path)?; + let contents_str = contents.as_str(); let properties = hashmap! { "Value".to_owned() => contents_str.into(),