diff --git a/src/change_processor.rs b/src/change_processor.rs index 88e727cb..a0d0518d 100644 --- a/src/change_processor.rs +++ b/src/change_processor.rs @@ -657,9 +657,8 @@ impl JobThreadContext { // If a rename handler already moved the file, // use the new path instead of the stale // instigating_source path. - let effective_path = overridden_source_path - .as_deref() - .unwrap_or(path.as_path()); + let effective_path = + overridden_source_path.as_deref().unwrap_or(path.as_path()); if old_is_script && new_is_script && effective_path.exists() { // Script-to-script transition: rename the file extension. diff --git a/src/web/api.rs b/src/web/api.rs index 4c2861b8..969d5a45 100644 --- a/src/web/api.rs +++ b/src/web/api.rs @@ -332,6 +332,10 @@ impl ApiService { // Process removed instances (syncback: delete files from Rojo filesystem) // Phase 1: Gather paths with the tree lock held. // Phase 2: Delete files without the lock. + // Only IDs that are actually removable (have a Path instigating source) + // are included in the PatchSet. ProjectNode instances are skipped so + // they are NOT removed from the in-memory tree. + let mut actually_removed: Vec = Vec::new(); if !request.removed.is_empty() { let removal_actions: Vec<(Ref, Option<(PathBuf, bool)>)> = { let tree = self.serve_session.tree(); @@ -371,6 +375,7 @@ impl ApiService { "Syncback: Path already removed (likely parent was deleted): {}", path.display() ); + actually_removed.push(id); continue; } if is_dir { @@ -384,6 +389,7 @@ impl ApiService { ); } else { log::info!("Syncback: Removed directory at {}", path.display()); + actually_removed.push(id); } } else { self.suppress_path(&path); @@ -396,6 +402,7 @@ impl ApiService { ); } else { log::info!("Syncback: Removed file at {}", path.display()); + actually_removed.push(id); } // Also remove adjacent meta file. // Strip known script suffixes (.server, .client, etc.) @@ -506,7 +513,7 @@ impl ApiService { tree_mutation_sender .send(PatchSet { - removed_instances: request.removed, + removed_instances: actually_removed, added_instances: Vec::new(), updated_instances, }) diff --git a/tests/tests/two_way_sync.rs b/tests/tests/two_way_sync.rs index 74c6a631..08157a3c 100644 --- a/tests/tests/two_way_sync.rs +++ b/tests/tests/two_way_sync.rs @@ -1154,13 +1154,9 @@ fn get_encoded_names_instance( #[test] fn add_child_to_encoded_module_creates_encoded_directory() { run_serve_test("syncback_encoded_names", |session, _redactions| { - let (session_id, encoded_module_id) = - get_encoded_names_instance(&session, "What?Module"); + let (session_id, encoded_module_id) = get_encoded_names_instance(&session, "What?Module"); - let standalone_file = session - .path() - .join("src") - .join("What%QUESTION%Module.luau"); + let standalone_file = session.path().join("src").join("What%QUESTION%Module.luau"); // The CORRECT directory name uses the encoded filesystem name let encoded_dir = session.path().join("src").join("What%QUESTION%Module"); // The WRONG directory name would use the decoded instance name @@ -1231,8 +1227,7 @@ fn add_child_to_encoded_module_creates_encoded_directory() { #[test] fn add_child_to_encoded_script_strips_suffix_correctly() { run_serve_test("syncback_encoded_names", |session, _redactions| { - let (session_id, encoded_script_id) = - get_encoded_names_instance(&session, "Key:Script"); + let (session_id, encoded_script_id) = get_encoded_names_instance(&session, "Key:Script"); let standalone_file = session .path() @@ -1304,8 +1299,7 @@ fn add_child_to_encoded_script_strips_suffix_correctly() { #[test] fn add_child_to_encoded_model_creates_encoded_directory() { run_serve_test("syncback_encoded_names", |session, _redactions| { - let (session_id, encoded_model_id) = - get_encoded_names_instance(&session, "What?Model"); + let (session_id, encoded_model_id) = get_encoded_names_instance(&session, "What?Model"); let standalone_file = session .path() @@ -1369,21 +1363,14 @@ fn add_child_to_encoded_model_creates_encoded_directory() { #[test] fn property_update_on_encoded_script_uses_encoded_meta_path() { run_serve_test("syncback_encoded_names", |session, _redactions| { - let (session_id, encoded_module_id) = - get_encoded_names_instance(&session, "What?Module"); + let (session_id, encoded_module_id) = get_encoded_names_instance(&session, "What?Module"); - let script_file = session - .path() - .join("src") - .join("What%QUESTION%Module.luau"); + let script_file = session.path().join("src").join("What%QUESTION%Module.luau"); let encoded_meta = session .path() .join("src") .join("What%QUESTION%Module.meta.json5"); - let decoded_meta = session - .path() - .join("src") - .join("What?Module.meta.json5"); + let decoded_meta = session.path().join("src").join("What?Module.meta.json5"); assert_file_exists(&script_file, "Encoded script file before property update"); assert_not_exists(&encoded_meta, "Meta file before property update");