mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-23 22:11:38 +00:00
Implement incremental syncback mode to preserve existing file structure
- Added an `incremental` flag to the `SyncbackCommand` to allow for preserving existing file structure and middleware formats during syncback operations. - Enhanced the `syncback_loop` function to differentiate between clean mode and incremental mode, ensuring orphaned files are removed only in clean mode. - Updated logging to reflect the mode of operation during syncback. - Introduced new tests to validate the behavior of clean mode versus incremental mode, ensuring proper handling of orphaned files and preservation of existing structures.
This commit is contained in:
parent
0e5e809894
commit
58399bb863
39 changed files with 652 additions and 119 deletions
|
|
@ -2,7 +2,9 @@ use std::ffi::OsStr;
|
|||
|
||||
use insta::assert_snapshot;
|
||||
|
||||
use crate::rojo_test::syncback_util::{run_syncback_test, snapshot_rbxm};
|
||||
use crate::rojo_test::syncback_util::{
|
||||
run_syncback_test, run_syncback_test_incremental, snapshot_rbxm,
|
||||
};
|
||||
|
||||
macro_rules! syncback_tests {
|
||||
($($test_name:ident => $list:expr$(,)?),*) => {$(
|
||||
|
|
@ -28,27 +30,47 @@ macro_rules! syncback_tests {
|
|||
)*};
|
||||
}
|
||||
|
||||
/// Tests that need to run in incremental mode (preserving existing structure)
|
||||
macro_rules! syncback_tests_incremental {
|
||||
($($test_name:ident => $list:expr$(,)?),*) => {$(
|
||||
#[test]
|
||||
fn $test_name() {
|
||||
run_syncback_test_incremental(stringify!($test_name), |path| {
|
||||
for name in $list {
|
||||
let snapshot_name = format!(concat!(stringify!($test_name), "-{}"), name);
|
||||
let new = path.join::<&str>(name);
|
||||
if !new.exists() {
|
||||
panic!("the path stub '{}' does not exist after syncback runs. consider double checking for typos.", name);
|
||||
}
|
||||
if let Some("rbxm") = new.extension().and_then(OsStr::to_str) {
|
||||
let content = fs_err::read(new).unwrap();
|
||||
snapshot_rbxm(&snapshot_name, content, name);
|
||||
} else {
|
||||
let content = fs_err::read_to_string(new).unwrap();
|
||||
assert_snapshot!(snapshot_name, content, name);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
)*};
|
||||
}
|
||||
|
||||
// Tests that run in clean mode (default)
|
||||
syncback_tests! {
|
||||
// Ensures that there's only one copy written to disk if navigating a
|
||||
// project file might yield two copies
|
||||
child_but_not => ["OnlyOneCopy/child_of_one.luau", "ReplicatedStorage/child_replicated_storage.luau"],
|
||||
// Ensures that syncback works with CSVs
|
||||
csv => ["src/csv_init/init.csv", "src/csv.csv"],
|
||||
// Ensures that if a RojoId is duplicated somewhere in the project, it's
|
||||
// rewritten rather than synced back as a conflict
|
||||
duplicate_rojo_id => ["container.model.json5"],
|
||||
// Ensures that the `ignorePaths` setting works for additions (new files get .json5)
|
||||
ignore_paths_adding => ["src/int_value.model.json5", "src/subfolder/string_value.txt"],
|
||||
// Ensures that the `ignorePaths` setting works for `init` files
|
||||
ignore_paths_init => ["src/non-init.luau", "src/init-file/init.luau"],
|
||||
// Ensures that the `ignorePaths` setting works for removals (new file gets .json5)
|
||||
ignore_paths_removing => ["src/Message.model.json5"],
|
||||
// Ensures that `ignoreTrees` works for additions
|
||||
ignore_trees_adding => [],
|
||||
// Ensures that `ignoreTrees` works for removals
|
||||
ignore_trees_removing => [],
|
||||
// Ensures that all of the JSON middlewares are handled as expected
|
||||
json_middlewares => ["src/dir_with_meta/init.meta.json5", "src/model_json.model.json5", "src/project_json.project.json5"],
|
||||
// Ensures projects that refer to other projects work as expected
|
||||
nested_projects => ["nested.project.json5", "string_value.txt"],
|
||||
// Ensures files that are ignored by nested projects are picked up if
|
||||
|
|
@ -62,28 +84,37 @@ syncback_tests! {
|
|||
project_reserialize => ["attribute_mismatch.luau", "property_mismatch.project.json5"],
|
||||
// Confirms that Instances that cannot serialize as directories serialize as rbxms
|
||||
rbxm_fallback => [],
|
||||
// Ensures that ref properties are linked properly on the file system
|
||||
ref_properties => ["src/pointer.model.json5", "src/target.model.json5"],
|
||||
// Ensures that ref properties are linked when no attributes are manually
|
||||
// set in the DataModel (new files get .json5)
|
||||
ref_properties_blank => ["src/pointer.model.json5", "src/target.txt"],
|
||||
// Ensures that if there is a conflict in RojoRefs, one of them is rewritten
|
||||
ref_properties_conflict => ["src/Pointer_2.model.json5", "src/Target_2.model.json5"],
|
||||
// Ensures that having multiple pointers that are aimed at the same target doesn't trigger ref rewrites.
|
||||
ref_properties_duplicate => [],
|
||||
// Ensures that ref properties that point to nothing after the prune both
|
||||
// do not leave any trace of themselves (new files get .json5)
|
||||
ref_properties_pruned => ["src/Pointer1.model.json5", "src/Pointer2.model.json5", "src/Pointer3.model.json5"],
|
||||
// Ensures that the old middleware is respected during syncback
|
||||
respect_old_middleware => ["default.project.json5", "src/model_json.model.json5", "src/rbxm.rbxm", "src/rbxmx.rbxmx"],
|
||||
// Ensures that the `$schema` field roundtrips with syncback
|
||||
schema_roundtrip => ["default.project.json5", "src/model.model.json5", "src/init/init.meta.json5", "src/adjacent.meta.json5"],
|
||||
// Ensures that StringValues inside project files are written to the
|
||||
// project file, but only if they don't have `$path` set
|
||||
string_value_project => ["default.project.json5"],
|
||||
// Ensures that sync rules are respected. This is really just a test to
|
||||
// ensure it uses the old path when possible, but we want the coverage.
|
||||
sync_rules => ["src/module.modulescript", "src/text.text"],
|
||||
// Ensures that the `syncUnscriptable` setting works
|
||||
unscriptable_properties => ["default.project.json5"],
|
||||
}
|
||||
|
||||
// Tests that run in incremental mode (preserving existing structure)
|
||||
syncback_tests_incremental! {
|
||||
// Ensures that syncback works with CSVs (preserves existing CSV structure)
|
||||
csv => ["src/csv_init/init.csv", "src/csv.csv"],
|
||||
// Ensures that the `ignorePaths` setting works for `init` files
|
||||
ignore_paths_init => ["src/non-init.luau", "src/init-file/init.luau"],
|
||||
// Ensures that all of the JSON middlewares are handled as expected
|
||||
json_middlewares => ["src/dir_with_meta/init.meta.json5", "src/model_json.model.json5", "src/project_json.project.json5"],
|
||||
// Ensures that ref properties are linked properly on the file system
|
||||
ref_properties => ["src/pointer.model.json5", "src/target.model.json5"],
|
||||
// Ensures that if there is a conflict in RojoRefs, one of them is rewritten
|
||||
ref_properties_conflict => ["src/Pointer_2.model.json5", "src/Target_2.model.json5"],
|
||||
// Ensures that the old middleware is respected during syncback (incremental mode only)
|
||||
respect_old_middleware => ["default.project.json5", "src/model_json.model.json5", "src/rbxm.rbxm", "src/rbxmx.rbxmx"],
|
||||
// Ensures that sync rules are respected (incremental mode only - uses old paths when possible)
|
||||
sync_rules => ["src/module.modulescript", "src/text.text"],
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue