Update vscode-rojo submodule reference and complete migration plan for path encoding

- Updated the vscode-rojo submodule to the latest commit.
- Marked all phases of the path encoding migration plan as completed, transitioning to a slugify and deduplication approach.
- Updated documentation to reflect changes in filename handling and metadata management.
This commit is contained in:
Joe 2026-02-10 03:14:18 -06:00
parent 0955e38b45
commit 126c8e66a4
77 changed files with 3512 additions and 799 deletions

File diff suppressed because it is too large Load diff

View file

@ -29,7 +29,10 @@ use crate::{
Project,
};
pub use file_names::{extension_for_middleware, name_for_inst, validate_file_name};
pub use file_names::{
deduplicate_name, extension_for_middleware, name_for_inst, name_needs_slugify, slugify_name,
validate_file_name,
};
pub use fs_snapshot::FsSnapshot;
pub use hash::*;
pub use property_filter::{
@ -996,12 +999,6 @@ pub struct SyncbackRules {
/// generally a better UX.
#[serde(skip_serializing_if = "Option::is_none")]
create_ignore_dir_paths: Option<bool>,
/// Whether to encode Windows-invalid characters in file names during
/// syncback. Characters like `<`, `>`, `:`, `"`, `/`, `\`, `|`, `?`, `*`
/// will be encoded as `%LT%`, `%GT%`, `%COLON%`, etc.
/// Defaults to `true`.
#[serde(skip_serializing_if = "Option::is_none")]
encode_windows_invalid_chars: Option<bool>,
/// When enabled, only "visible" services will be synced back. This includes
/// commonly used services like Workspace, ReplicatedStorage, ServerScriptService,
/// etc., while ignoring internal/hidden services like Chat, HttpService, etc.
@ -1054,13 +1051,6 @@ impl SyncbackRules {
Ok(globs)
}
/// Returns whether special characters (including periods) should be encoded
/// in file names during syncback. Defaults to `true`.
#[inline]
pub fn encode_windows_invalid_chars(&self) -> bool {
self.encode_windows_invalid_chars.unwrap_or(true)
}
/// Returns whether hidden/internal services should be ignored during
/// syncback. When `true`, only visible services like Workspace,
/// ReplicatedStorage, etc. will be synced. Defaults to `true`.

View file

@ -1,5 +1,6 @@
use indexmap::IndexMap;
use memofs::Vfs;
use std::collections::HashSet;
use std::path::{Path, PathBuf};
use crate::{
@ -56,7 +57,12 @@ impl<'sync> SyncbackSnapshot<'sync> {
/// In clean mode (incremental=false), old_ref is ignored and set to None,
/// ensuring fresh filenames and middleware choices for all children.
#[inline]
pub fn with_joined_path(&self, new_ref: Ref, old_ref: Option<Ref>) -> anyhow::Result<Self> {
pub fn with_joined_path(
&self,
new_ref: Ref,
old_ref: Option<Ref>,
taken_names: &HashSet<String>,
) -> anyhow::Result<(Self, bool)> {
// In clean mode, ignore old_ref to ensure fresh structure
let effective_old_ref = if self.data.incremental { old_ref } else { None };
let mut snapshot = Self {
@ -67,16 +73,15 @@ impl<'sync> SyncbackSnapshot<'sync> {
middleware: None,
};
let middleware = get_best_middleware(&snapshot);
let encode_invalid_chars = self.encode_windows_invalid_chars();
let name = name_for_inst(
let (name, needs_meta_name) = name_for_inst(
middleware,
snapshot.new_inst(),
snapshot.old_inst(),
encode_invalid_chars,
taken_names,
)?;
snapshot.path = self.path.join(name.as_ref());
snapshot.path = self.path.join(&*name);
Ok(snapshot)
Ok((snapshot, needs_meta_name))
}
/// Constructs a SyncbackSnapshot from the provided refs and a base path,
@ -93,7 +98,8 @@ impl<'sync> SyncbackSnapshot<'sync> {
base_path: &Path,
new_ref: Ref,
old_ref: Option<Ref>,
) -> anyhow::Result<Self> {
taken_names: &HashSet<String>,
) -> anyhow::Result<(Self, bool)> {
// In clean mode, ignore old_ref to ensure fresh structure
let effective_old_ref = if self.data.incremental { old_ref } else { None };
let mut snapshot = Self {
@ -104,16 +110,15 @@ impl<'sync> SyncbackSnapshot<'sync> {
middleware: None,
};
let middleware = get_best_middleware(&snapshot);
let encode_invalid_chars = self.encode_windows_invalid_chars();
let name = name_for_inst(
let (name, needs_meta_name) = name_for_inst(
middleware,
snapshot.new_inst(),
snapshot.old_inst(),
encode_invalid_chars,
taken_names,
)?;
snapshot.path = base_path.join(name.as_ref());
snapshot.path = base_path.join(&*name);
Ok(snapshot)
Ok((snapshot, needs_meta_name))
}
/// Constructs a SyncbackSnapshot with the provided path and refs while
@ -319,18 +324,6 @@ impl<'sync> SyncbackSnapshot<'sync> {
.unwrap_or_default()
}
/// Returns whether Windows-invalid characters should be encoded in file
/// names during syncback. Defaults to `true`.
#[inline]
pub fn encode_windows_invalid_chars(&self) -> bool {
self.data
.project
.syncback_rules
.as_ref()
.map(|rules| rules.encode_windows_invalid_chars())
.unwrap_or(true)
}
/// Returns whether to emit warnings when duplicate child names are
/// encountered during syncback. Defaults to `false` (suppressed).
#[inline]