Fix rojo plugin install by adding Vfs::exists (#1169)

This commit is contained in:
Ken Loeffler
2025-11-21 15:04:34 +00:00
committed by GitHub
parent 015b5bda14
commit 93e9c51204
7 changed files with 51 additions and 9 deletions

View File

@@ -1,11 +1,15 @@
# memofs Changelog # memofs Changelog
## Unreleased Changes ## Unreleased Changes
* Added `Vfs::exists`. [#1169]
* Added `create_dir` and `create_dir_all` to allow creating directories. [#937]
[#1169]: https://github.com/rojo-rbx/rojo/pull/1169
[#937]: https://github.com/rojo-rbx/rojo/pull/937
## 0.3.0 (2024-03-15) ## 0.3.0 (2024-03-15)
* Changed `StdBackend` file watching component to use minimal recursive watches. [#830] * Changed `StdBackend` file watching component to use minimal recursive watches. [#830]
* Added `Vfs::read_to_string` and `Vfs::read_to_string_lf_normalized` [#854] * Added `Vfs::read_to_string` and `Vfs::read_to_string_lf_normalized` [#854]
* Added `create_dir` and `create_dir_all` to allow creating directories.
[#830]: https://github.com/rojo-rbx/rojo/pull/830 [#830]: https://github.com/rojo-rbx/rojo/pull/830
[#854]: https://github.com/rojo-rbx/rojo/pull/854 [#854]: https://github.com/rojo-rbx/rojo/pull/854

View File

@@ -157,6 +157,11 @@ impl VfsBackend for InMemoryFs {
) )
} }
fn exists(&mut self, path: &Path) -> io::Result<bool> {
let inner = self.inner.lock().unwrap();
Ok(inner.entries.contains_key(path))
}
fn read_dir(&mut self, path: &Path) -> io::Result<ReadDir> { fn read_dir(&mut self, path: &Path) -> io::Result<ReadDir> {
let inner = self.inner.lock().unwrap(); let inner = self.inner.lock().unwrap();

View File

@@ -70,6 +70,7 @@ impl<T> IoResultExt<T> for io::Result<T> {
pub trait VfsBackend: sealed::Sealed + Send + 'static { pub trait VfsBackend: sealed::Sealed + Send + 'static {
fn read(&mut self, path: &Path) -> io::Result<Vec<u8>>; fn read(&mut self, path: &Path) -> io::Result<Vec<u8>>;
fn write(&mut self, path: &Path, data: &[u8]) -> io::Result<()>; fn write(&mut self, path: &Path, data: &[u8]) -> io::Result<()>;
fn exists(&mut self, path: &Path) -> io::Result<bool>;
fn read_dir(&mut self, path: &Path) -> io::Result<ReadDir>; fn read_dir(&mut self, path: &Path) -> io::Result<ReadDir>;
fn create_dir(&mut self, path: &Path) -> io::Result<()>; fn create_dir(&mut self, path: &Path) -> io::Result<()>;
fn create_dir_all(&mut self, path: &Path) -> io::Result<()>; fn create_dir_all(&mut self, path: &Path) -> io::Result<()>;
@@ -175,6 +176,11 @@ impl VfsInner {
Ok(Arc::new(contents_str.into())) Ok(Arc::new(contents_str.into()))
} }
fn exists<P: AsRef<Path>>(&mut self, path: P) -> io::Result<bool> {
let path = path.as_ref();
self.backend.exists(path)
}
fn write<P: AsRef<Path>, C: AsRef<[u8]>>(&mut self, path: P, contents: C) -> io::Result<()> { fn write<P: AsRef<Path>, C: AsRef<[u8]>>(&mut self, path: P, contents: C) -> io::Result<()> {
let path = path.as_ref(); let path = path.as_ref();
let contents = contents.as_ref(); let contents = contents.as_ref();
@@ -338,6 +344,17 @@ impl Vfs {
self.inner.lock().unwrap().read_dir(path) self.inner.lock().unwrap().read_dir(path)
} }
/// Return whether the given path exists.
///
/// Roughly equivalent to [`std::fs::exists`][std::fs::exists].
///
/// [std::fs::exists]: https://doc.rust-lang.org/stable/std/fs/fn.exists.html
#[inline]
pub fn exists<P: AsRef<Path>>(&self, path: P) -> io::Result<bool> {
let path = path.as_ref();
self.inner.lock().unwrap().exists(path)
}
/// Creates a directory at the provided location. /// Creates a directory at the provided location.
/// ///
/// Roughly equivalent to [`std::fs::create_dir`][std::fs::create_dir]. /// Roughly equivalent to [`std::fs::create_dir`][std::fs::create_dir].

View File

@@ -22,6 +22,10 @@ impl VfsBackend for NoopBackend {
Err(io::Error::other("NoopBackend doesn't do anything")) Err(io::Error::other("NoopBackend doesn't do anything"))
} }
fn exists(&mut self, _path: &Path) -> io::Result<bool> {
Err(io::Error::other("NoopBackend doesn't do anything"))
}
fn read_dir(&mut self, _path: &Path) -> io::Result<ReadDir> { fn read_dir(&mut self, _path: &Path) -> io::Result<ReadDir> {
Err(io::Error::other("NoopBackend doesn't do anything")) Err(io::Error::other("NoopBackend doesn't do anything"))
} }

View File

@@ -63,6 +63,10 @@ impl VfsBackend for StdBackend {
fs_err::write(path, data) fs_err::write(path, data)
} }
fn exists(&mut self, path: &Path) -> io::Result<bool> {
std::fs::exists(path)
}
fn read_dir(&mut self, path: &Path) -> io::Result<ReadDir> { fn read_dir(&mut self, path: &Path) -> io::Result<ReadDir> {
let entries: Result<Vec<_>, _> = fs_err::read_dir(path)?.collect(); let entries: Result<Vec<_>, _> = fs_err::read_dir(path)?.collect();
let mut entries = entries?; let mut entries = entries?;

View File

@@ -46,10 +46,18 @@ impl PluginSubcommand {
} }
} }
fn install_plugin() -> anyhow::Result<()> { fn initialize_plugin() -> anyhow::Result<ServeSession> {
let plugin_snapshot: VfsSnapshot = bincode::deserialize(PLUGIN_BINCODE) let plugin_snapshot: VfsSnapshot = bincode::deserialize(PLUGIN_BINCODE)
.expect("Rojo's plugin was not properly packed into Rojo's binary"); .expect("Rojo's plugin was not properly packed into Rojo's binary");
let mut in_memory_fs = InMemoryFs::new();
in_memory_fs.load_snapshot("/plugin", plugin_snapshot)?;
let vfs = Vfs::new(in_memory_fs);
Ok(ServeSession::new(vfs, "/plugin")?)
}
fn install_plugin() -> anyhow::Result<()> {
let studio = RobloxStudio::locate()?; let studio = RobloxStudio::locate()?;
let plugins_folder_path = studio.plugins_path(); let plugins_folder_path = studio.plugins_path();
@@ -59,17 +67,12 @@ fn install_plugin() -> anyhow::Result<()> {
fs::create_dir(plugins_folder_path)?; fs::create_dir(plugins_folder_path)?;
} }
let mut in_memory_fs = InMemoryFs::new();
in_memory_fs.load_snapshot("/plugin", plugin_snapshot)?;
let vfs = Vfs::new(in_memory_fs);
let session = ServeSession::new(vfs, "/plugin")?;
let plugin_path = plugins_folder_path.join(PLUGIN_FILE_NAME); let plugin_path = plugins_folder_path.join(PLUGIN_FILE_NAME);
log::debug!("Writing plugin to {}", plugin_path.display()); log::debug!("Writing plugin to {}", plugin_path.display());
let mut file = BufWriter::new(File::create(plugin_path)?); let mut file = BufWriter::new(File::create(plugin_path)?);
let session = initialize_plugin()?;
let tree = session.tree(); let tree = session.tree();
let root_id = tree.get_root_id(); let root_id = tree.get_root_id();
@@ -92,3 +95,8 @@ fn uninstall_plugin() -> anyhow::Result<()> {
Ok(()) Ok(())
} }
#[test]
fn plugin_initialize() {
assert!(initialize_plugin().is_ok())
}

View File

@@ -295,7 +295,7 @@ impl Project {
// Check for default projects. // Check for default projects.
for default_project_name in DEFAULT_PROJECT_NAMES { for default_project_name in DEFAULT_PROJECT_NAMES {
let project_path = path.join(default_project_name); let project_path = path.join(default_project_name);
if project_path.exists() { if let Ok(true) = vfs.exists(&project_path) {
return Self::load_exact(vfs, &project_path, None); return Self::load_exact(vfs, &project_path, None);
} }
} }