mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-23 14:01:37 +00:00
Refactor change processing and metadata handling for improved clarity
- Removed the `dedup_against_dir` method from `JobThreadContext`, simplifying the slug deduplication logic during file operations. - Streamlined the slugification process by directly assigning the slugified name without intermediate variables, enhancing readability. - Consolidated metadata path handling in `ApiService`, improving code organization and reducing redundancy in path construction. - Updated comments for better understanding of the changes made to slugification and metadata processing.
This commit is contained in:
parent
7d47fe73f6
commit
085e1ab3f5
2 changed files with 16 additions and 85 deletions
|
|
@ -15,7 +15,7 @@ use crate::{
|
||||||
apply_patch_set, compute_patch_set, AppliedPatchSet, InstigatingSource, PatchSet, RojoTree,
|
apply_patch_set, compute_patch_set, AppliedPatchSet, InstigatingSource, PatchSet, RojoTree,
|
||||||
},
|
},
|
||||||
snapshot_middleware::{snapshot_from_vfs, snapshot_project_node},
|
snapshot_middleware::{snapshot_from_vfs, snapshot_project_node},
|
||||||
syncback::{deduplicate_name, name_needs_slugify, slugify_name},
|
syncback::{name_needs_slugify, slugify_name},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Processes file change events, updates the DOM, and sends those updates
|
/// Processes file change events, updates the DOM, and sends those updates
|
||||||
|
|
@ -311,42 +311,6 @@ impl JobThreadContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deduplicate a slugified name against existing entries in a parent
|
|
||||||
/// directory. Reads the directory, strips entries to bare slugs (file_stem),
|
|
||||||
/// and uses `deduplicate_name` to find a collision-free name.
|
|
||||||
fn dedup_against_dir(slug: &str, parent_dir: &Path, exclude: Option<&str>) -> String {
|
|
||||||
let mut taken = std::collections::HashSet::new();
|
|
||||||
if let Ok(entries) = fs::read_dir(parent_dir) {
|
|
||||||
for entry in entries.flatten() {
|
|
||||||
let name = entry.file_name();
|
|
||||||
let name_str = name.to_string_lossy();
|
|
||||||
// Use file_stem as a rough bare-slug approximation.
|
|
||||||
// For directories this is the dir name itself; for files
|
|
||||||
// it strips the last extension (e.g., "foo.server" from
|
|
||||||
// "foo.server.luau"). This is conservative: it may over-
|
|
||||||
// dedup in rare cases (compound extensions) but never
|
|
||||||
// under-dedup.
|
|
||||||
let stem = if entry.path().is_dir() {
|
|
||||||
name_str.to_string()
|
|
||||||
} else {
|
|
||||||
std::path::Path::new(name_str.as_ref())
|
|
||||||
.file_stem()
|
|
||||||
.and_then(|s| s.to_str())
|
|
||||||
.unwrap_or(&name_str)
|
|
||||||
.to_string()
|
|
||||||
};
|
|
||||||
// Exclude the entry being renamed (it will be gone after rename)
|
|
||||||
if let Some(ex) = exclude {
|
|
||||||
if name_str == ex {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
taken.insert(stem.to_lowercase());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
deduplicate_name(slug, &taken)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Computes and applies patches to the DOM for a given file path.
|
/// Computes and applies patches to the DOM for a given file path.
|
||||||
///
|
///
|
||||||
/// This function finds the nearest ancestor to the given path that has associated instances
|
/// This function finds the nearest ancestor to the given path that has associated instances
|
||||||
|
|
@ -759,22 +723,12 @@ impl JobThreadContext {
|
||||||
.and_then(|f| f.to_str())
|
.and_then(|f| f.to_str())
|
||||||
.unwrap_or("");
|
.unwrap_or("");
|
||||||
// Slugify the new name for filesystem safety
|
// Slugify the new name for filesystem safety
|
||||||
let mut slugified_new_name =
|
let slugified_new_name =
|
||||||
if name_needs_slugify(new_name) {
|
if name_needs_slugify(new_name) {
|
||||||
slugify_name(new_name)
|
slugify_name(new_name)
|
||||||
} else {
|
} else {
|
||||||
new_name.to_string()
|
new_name.to_string()
|
||||||
};
|
};
|
||||||
// Dedup against siblings to avoid overwriting
|
|
||||||
// an existing directory at the target path
|
|
||||||
let candidate = grandparent.join(&slugified_new_name);
|
|
||||||
if candidate.exists() && candidate != dir_path {
|
|
||||||
slugified_new_name = Self::dedup_against_dir(
|
|
||||||
&slugified_new_name,
|
|
||||||
grandparent,
|
|
||||||
dir_path.file_name().and_then(|s| s.to_str()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let new_dir_path =
|
let new_dir_path =
|
||||||
grandparent.join(&slugified_new_name);
|
grandparent.join(&slugified_new_name);
|
||||||
|
|
||||||
|
|
@ -862,33 +816,12 @@ impl JobThreadContext {
|
||||||
&stem[..stem.len() - script_suffix.len()]
|
&stem[..stem.len() - script_suffix.len()]
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut slugified_new_name =
|
let slugified_new_name = if name_needs_slugify(new_name)
|
||||||
if name_needs_slugify(new_name) {
|
{
|
||||||
slugify_name(new_name)
|
slugify_name(new_name)
|
||||||
} else {
|
|
||||||
new_name.to_string()
|
|
||||||
};
|
|
||||||
// Dedup against siblings to avoid overwriting
|
|
||||||
// an existing file at the target path
|
|
||||||
let test_file_name = if extension.is_empty() {
|
|
||||||
format!("{}{}", slugified_new_name, script_suffix)
|
|
||||||
} else {
|
} else {
|
||||||
format!(
|
new_name.to_string()
|
||||||
"{}{}.{}",
|
|
||||||
slugified_new_name, script_suffix, extension
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
let test_path = parent.join(&test_file_name);
|
|
||||||
if test_path.exists() && test_path != *path {
|
|
||||||
let old_filename = path
|
|
||||||
.file_name()
|
|
||||||
.and_then(|s| s.to_str());
|
|
||||||
slugified_new_name = Self::dedup_against_dir(
|
|
||||||
&slugified_new_name,
|
|
||||||
parent,
|
|
||||||
old_filename,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let new_file_name = if extension.is_empty() {
|
let new_file_name = if extension.is_empty() {
|
||||||
format!("{}{}", slugified_new_name, script_suffix)
|
format!("{}{}", slugified_new_name, script_suffix)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -574,10 +574,7 @@ impl ApiService {
|
||||||
adds_by_parent.entry(parent_ref).or_default().push(added);
|
adds_by_parent.entry(parent_ref).or_default().push(added);
|
||||||
} else {
|
} else {
|
||||||
// No parent — process individually (will fail with context)
|
// No parent — process individually (will fail with context)
|
||||||
adds_by_parent
|
adds_by_parent.entry(Ref::none()).or_default().push(added);
|
||||||
.entry(Ref::none())
|
|
||||||
.or_default()
|
|
||||||
.push(added);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (parent_ref, siblings) in &adds_by_parent {
|
for (parent_ref, siblings) in &adds_by_parent {
|
||||||
|
|
@ -1954,8 +1951,7 @@ impl ApiService {
|
||||||
indexmap::IndexMap::new(),
|
indexmap::IndexMap::new(),
|
||||||
indexmap::IndexMap::new(),
|
indexmap::IndexMap::new(),
|
||||||
);
|
);
|
||||||
let meta_path =
|
let meta_path = parent_dir.join(format!("{}.meta.json5", encoded_name));
|
||||||
parent_dir.join(format!("{}.meta.json5", encoded_name));
|
|
||||||
let content = crate::json::to_vec_pretty_sorted(&meta)
|
let content = crate::json::to_vec_pretty_sorted(&meta)
|
||||||
.context("Failed to serialize meta")?;
|
.context("Failed to serialize meta")?;
|
||||||
self.suppress_path(&meta_path);
|
self.suppress_path(&meta_path);
|
||||||
|
|
@ -2005,8 +2001,7 @@ impl ApiService {
|
||||||
indexmap::IndexMap::new(),
|
indexmap::IndexMap::new(),
|
||||||
indexmap::IndexMap::new(),
|
indexmap::IndexMap::new(),
|
||||||
);
|
);
|
||||||
let meta_path =
|
let meta_path = parent_dir.join(format!("{}.meta.json5", encoded_name));
|
||||||
parent_dir.join(format!("{}.meta.json5", encoded_name));
|
|
||||||
let content = crate::json::to_vec_pretty_sorted(&meta)
|
let content = crate::json::to_vec_pretty_sorted(&meta)
|
||||||
.context("Failed to serialize meta")?;
|
.context("Failed to serialize meta")?;
|
||||||
self.suppress_path(&meta_path);
|
self.suppress_path(&meta_path);
|
||||||
|
|
@ -2061,8 +2056,7 @@ impl ApiService {
|
||||||
// Recursively process children
|
// Recursively process children
|
||||||
self.process_children_incremental(&unique_children, &dir_path, stats)?;
|
self.process_children_incremental(&unique_children, &dir_path, stats)?;
|
||||||
} else {
|
} else {
|
||||||
let content =
|
let content = self.serialize_instance_to_model_json(added, meta_name_field)?;
|
||||||
self.serialize_instance_to_model_json(added, meta_name_field)?;
|
|
||||||
// Use the detected file path if available (preserves .model.json
|
// Use the detected file path if available (preserves .model.json
|
||||||
// vs .model.json5), otherwise default to .model.json5
|
// vs .model.json5), otherwise default to .model.json5
|
||||||
let file_path = match &existing_format {
|
let file_path = match &existing_format {
|
||||||
|
|
@ -2210,8 +2204,12 @@ impl ApiService {
|
||||||
self.filter_properties_for_meta(&added.class_name, &added.properties, None);
|
self.filter_properties_for_meta(&added.class_name, &added.properties, None);
|
||||||
|
|
||||||
// For non-Folder classes, we need to include className
|
// For non-Folder classes, we need to include className
|
||||||
let meta =
|
let meta = self.build_meta_object(
|
||||||
self.build_meta_object(Some(&added.class_name), instance_name, properties, attributes);
|
Some(&added.class_name),
|
||||||
|
instance_name,
|
||||||
|
properties,
|
||||||
|
attributes,
|
||||||
|
);
|
||||||
let meta_path = dir_path.join("init.meta.json5");
|
let meta_path = dir_path.join("init.meta.json5");
|
||||||
let content = crate::json::to_vec_pretty_sorted(&meta)
|
let content = crate::json::to_vec_pretty_sorted(&meta)
|
||||||
.context("Failed to serialize init.meta.json5")?;
|
.context("Failed to serialize init.meta.json5")?;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue