Refactor syncback process to improve clean mode handling and directory management

- Removed the ensure_project_paths_exist function, streamlining the syncback process by directly managing directory creation and cleanup within the syncback command.
- Enhanced error handling for sourcemap generation, logging warnings when clean mode removes directories that only contain meta files.
- Updated the logic for middleware selection in clean mode to better handle directory and script transitions based on the filesystem structure.
- Added utility functions to ensure base project directories exist before syncback, addressing the need for directory structure in clean mode.
- Improved test coverage for clean mode scenarios, ensuring that directory existence checks are performed and documented.
This commit is contained in:
Joe 2026-02-01 19:55:54 -06:00
parent 1f476d6cc9
commit 1534a54808
6 changed files with 229 additions and 104 deletions

View file

@ -28,52 +28,6 @@ use super::{
GlobalOptions,
};
/// In clean mode, ensures all $path directories exist before loading the project.
/// This allows syncback to restore deleted directories.
fn ensure_project_paths_exist(project_path: &Path, vfs: &Vfs) -> anyhow::Result<()> {
// Load the project file (handles both file and directory paths)
let project = Project::load_initial_project(vfs, project_path)
.with_context(|| format!("Failed to load project file: {}", project_path.display()))?;
let base_path = project.folder_location();
// Recursively find all $path entries in the project tree
fn collect_paths(node: &crate::project::ProjectNode, base: &Path, paths: &mut Vec<PathBuf>) {
if let Some(ref path_node) = node.path {
let full_path = if path_node.path().is_absolute() {
path_node.path().to_path_buf()
} else {
base.join(path_node.path())
};
paths.push(full_path);
}
for child in node.children.values() {
collect_paths(child, base, paths);
}
}
let mut paths_to_check = Vec::new();
collect_paths(&project.tree, base_path, &mut paths_to_check);
// Create missing directories
for path in paths_to_check {
if !path.exists() {
log::debug!(
"Clean mode: creating missing $path directory: {}",
path.display()
);
std::fs::create_dir_all(&path).with_context(|| {
format!(
"Failed to create directory for $path: {}",
path.display()
)
})?;
}
}
Ok(())
}
const UNKNOWN_INPUT_KIND_ERR: &str = "Could not detect what kind of file was inputted. \
Expected input file to end in .rbxl, .rbxlx, .rbxm, or .rbxmx.";
@ -185,12 +139,6 @@ impl SyncbackCommand {
// watcher errors shouldn't terminate the process
let vfs = Vfs::new_oneshot();
// In clean mode, ensure all $path directories exist before loading
// the project. This allows syncback to restore deleted directories.
if !self.incremental {
ensure_project_paths_exist(&path_old, &vfs)?;
}
let project_start_timer = Instant::now();
let session_old = ServeSession::new(vfs, path_old.clone())?;
log::debug!(
@ -271,19 +219,35 @@ impl SyncbackCommand {
// Generate sourcemap after successful syncback.
// We need a fresh session that reads the post-syncback filesystem state,
// since session_old contains the pre-syncback tree.
//
// Note: This may fail if clean mode removed directories that the project
// references. This is expected for projects that have meta-only directories
// (e.g., `$path` pointing to a folder with only init.meta.json5). In such
// cases, we log a warning but don't fail the syncback.
let sourcemap_path = base_path.join("sourcemap.json");
let sourcemap_vfs = Vfs::new_oneshot();
let sourcemap_session = ServeSession::new(sourcemap_vfs, path_old.clone())?;
write_sourcemap(
&sourcemap_session,
Some(&sourcemap_path),
filter_nothing,
false,
true,
)?;
log::info!("Generated sourcemap at {}", sourcemap_path.display());
// Avoid expensive drop
forget(sourcemap_session);
match ServeSession::new(sourcemap_vfs, path_old.clone()) {
Ok(sourcemap_session) => {
write_sourcemap(
&sourcemap_session,
Some(&sourcemap_path),
filter_nothing,
false,
true,
)?;
log::info!("Generated sourcemap at {}", sourcemap_path.display());
// Avoid expensive drop
forget(sourcemap_session);
}
Err(e) => {
log::warn!(
"Could not generate sourcemap after syncback: {}. \
This can happen when clean mode removes directories that \
only contain meta files.",
e
);
}
}
// Refresh git index if in a git repository
refresh_git_index(base_path);