Implement Syncback to support converting Roblox files to a Rojo project (#937)

This is a very large commit.
Consider checking the linked PR for more information.
This commit is contained in:
Micah
2025-11-19 09:21:33 -08:00
committed by GitHub
parent 071b6e7e23
commit 9b5a07191b
239 changed files with 5325 additions and 225 deletions

View File

@@ -1,11 +1,16 @@
use std::{path::Path, str};
use anyhow::Context as _;
use memofs::Vfs;
use rbx_dom_weak::types::Variant;
use rbx_dom_weak::ustr;
use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot};
use crate::{
snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot},
syncback::{FsSnapshot, SyncbackReturn, SyncbackSnapshot},
};
use super::meta_file::AdjacentMetadata;
use super::{meta_file::AdjacentMetadata, PathExt as _};
pub fn snapshot_txt(
context: &InstanceContext,
@@ -32,6 +37,41 @@ pub fn snapshot_txt(
Ok(Some(snapshot))
}
pub fn syncback_txt<'sync>(
snapshot: &SyncbackSnapshot<'sync>,
) -> anyhow::Result<SyncbackReturn<'sync>> {
let new_inst = snapshot.new_inst();
let contents = if let Some(Variant::String(source)) = new_inst.properties.get(&ustr("Value")) {
source.as_bytes().to_vec()
} else {
anyhow::bail!("StringValues must have a `Value` property that is a String");
};
let mut fs_snapshot = FsSnapshot::new();
fs_snapshot.add_file(&snapshot.path, contents);
let meta = AdjacentMetadata::from_syncback_snapshot(snapshot, snapshot.path.clone())?;
if let Some(mut meta) = meta {
// StringValues have relatively few properties that we care about, so
// shifting is fine.
meta.properties.shift_remove(&ustr("Value"));
if !meta.is_empty() {
let parent = snapshot.path.parent_err()?;
fs_snapshot.add_file(
parent.join(format!("{}.meta.json", new_inst.name)),
serde_json::to_vec_pretty(&meta).context("could not serialize metadata")?,
);
}
}
Ok(SyncbackReturn {
fs_snapshot,
children: Vec::new(),
removed_children: Vec::new(),
})
}
#[cfg(test)]
mod test {
use super::*;