mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-23 14:01:37 +00:00
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:
parent
0955e38b45
commit
126c8e66a4
77 changed files with 3512 additions and 799 deletions
|
|
@ -10,9 +10,8 @@ use rbx_dom_weak::{types::Variant, ustr};
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
path_encoding::encode_path_name,
|
||||
snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot},
|
||||
syncback::{FsSnapshot, SyncbackReturn, SyncbackSnapshot},
|
||||
syncback::{name_needs_slugify, slugify_name, FsSnapshot, SyncbackReturn, SyncbackSnapshot},
|
||||
};
|
||||
|
||||
use super::{
|
||||
|
|
@ -110,10 +109,11 @@ pub fn syncback_csv<'sync>(
|
|||
|
||||
if !meta.is_empty() {
|
||||
let parent = snapshot.path.parent_err()?;
|
||||
let meta_name = if snapshot.encode_windows_invalid_chars() {
|
||||
encode_path_name(&new_inst.name)
|
||||
let instance_name = &new_inst.name;
|
||||
let meta_name = if name_needs_slugify(instance_name) {
|
||||
slugify_name(instance_name)
|
||||
} else {
|
||||
new_inst.name.clone()
|
||||
instance_name.clone()
|
||||
};
|
||||
fs_snapshot.add_file(
|
||||
parent.join(format!("{}.meta.json5", meta_name)),
|
||||
|
|
|
|||
|
|
@ -138,6 +138,25 @@ pub fn syncback_dir_no_meta<'sync>(
|
|||
let mut children = Vec::new();
|
||||
let mut removed_children = Vec::new();
|
||||
|
||||
// Seed taken_names with existing files on disk so new children don't
|
||||
// collide with files already present in the directory.
|
||||
let mut taken_names: HashSet<String> = snapshot
|
||||
.vfs()
|
||||
.read_dir(&snapshot.path)
|
||||
.ok()
|
||||
.map(|entries| {
|
||||
entries
|
||||
.filter_map(|e| e.ok())
|
||||
.filter_map(|e| {
|
||||
e.path()
|
||||
.file_name()
|
||||
.and_then(|n| n.to_str())
|
||||
.map(|n| n.to_lowercase())
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
// Detect duplicate child names (case-insensitive for file system safety).
|
||||
// We skip duplicates instead of failing, tracking them in stats.
|
||||
let mut child_name_counts: HashMap<String, usize> = HashMap::new();
|
||||
|
|
@ -220,10 +239,23 @@ pub fn syncback_dir_no_meta<'sync>(
|
|||
continue;
|
||||
}
|
||||
// This child exists in both doms. Pass it on.
|
||||
children.push(snapshot.with_joined_path(*new_child_ref, Some(old_child.id()))?);
|
||||
let (child_snap, _needs_meta) = snapshot.with_joined_path(
|
||||
*new_child_ref,
|
||||
Some(old_child.id()),
|
||||
&taken_names,
|
||||
)?;
|
||||
if let Some(name) = child_snap.path.file_name().and_then(|n| n.to_str()) {
|
||||
taken_names.insert(name.to_lowercase());
|
||||
}
|
||||
children.push(child_snap);
|
||||
} else {
|
||||
// The child only exists in the the new dom
|
||||
children.push(snapshot.with_joined_path(*new_child_ref, None)?);
|
||||
let (child_snap, _needs_meta) =
|
||||
snapshot.with_joined_path(*new_child_ref, None, &taken_names)?;
|
||||
if let Some(name) = child_snap.path.file_name().and_then(|n| n.to_str()) {
|
||||
taken_names.insert(name.to_lowercase());
|
||||
}
|
||||
children.push(child_snap);
|
||||
}
|
||||
}
|
||||
// Any children that are in the old dom but not the new one are removed.
|
||||
|
|
@ -267,7 +299,12 @@ pub fn syncback_dir_no_meta<'sync>(
|
|||
if snapshot.should_ignore_tree(*new_child_ref) {
|
||||
continue;
|
||||
}
|
||||
children.push(snapshot.with_joined_path(*new_child_ref, None)?);
|
||||
let (child_snap, _needs_meta) =
|
||||
snapshot.with_joined_path(*new_child_ref, None, &taken_names)?;
|
||||
if let Some(name) = child_snap.path.file_name().and_then(|n| n.to_str()) {
|
||||
taken_names.insert(name.to_lowercase());
|
||||
}
|
||||
children.push(child_snap);
|
||||
}
|
||||
}
|
||||
let mut fs_snapshot = FsSnapshot::new();
|
||||
|
|
|
|||
|
|
@ -35,20 +35,14 @@ pub fn snapshot_json_model(
|
|||
format!("File is not a valid JSON model: {}", path.display())
|
||||
})?;
|
||||
|
||||
if let Some(top_level_name) = &instance.name {
|
||||
let new_name = format!("{}.model.json5", top_level_name);
|
||||
// If the JSON has a name property, preserve it in metadata for syncback
|
||||
let specified_name = instance.name.clone();
|
||||
|
||||
log::warn!(
|
||||
"Model at path {} had a top-level Name field. \
|
||||
This field has been ignored since Rojo 6.0.\n\
|
||||
Consider removing this field and renaming the file to {}.",
|
||||
new_name,
|
||||
path.display()
|
||||
);
|
||||
// Use the name from JSON if present, otherwise fall back to filename-derived name
|
||||
if instance.name.is_none() {
|
||||
instance.name = Some(name.to_owned());
|
||||
}
|
||||
|
||||
instance.name = Some(name.to_owned());
|
||||
|
||||
let id = instance.id.take().map(RojoRef::new);
|
||||
let schema = instance.schema.take();
|
||||
|
||||
|
|
@ -62,7 +56,8 @@ pub fn snapshot_json_model(
|
|||
.relevant_paths(vec![vfs.canonicalize(path)?])
|
||||
.context(context)
|
||||
.specified_id(id)
|
||||
.schema(schema);
|
||||
.schema(schema)
|
||||
.specified_name(specified_name);
|
||||
|
||||
Ok(Some(snapshot))
|
||||
}
|
||||
|
|
@ -81,6 +76,7 @@ pub fn syncback_json_model<'sync>(
|
|||
// schemas will ever exist in one project for it to matter, but it
|
||||
// could have a performance cost.
|
||||
model.schema = old_inst.metadata().schema.clone();
|
||||
model.name = old_inst.metadata().specified_name.clone();
|
||||
}
|
||||
|
||||
let serialized = match crate::json::to_vec_pretty_sorted(&model) {
|
||||
|
|
|
|||
|
|
@ -8,9 +8,8 @@ use rbx_dom_weak::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
path_encoding::encode_path_name,
|
||||
snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot},
|
||||
syncback::{FsSnapshot, SyncbackReturn, SyncbackSnapshot},
|
||||
syncback::{name_needs_slugify, slugify_name, FsSnapshot, SyncbackReturn, SyncbackSnapshot},
|
||||
};
|
||||
|
||||
use super::{
|
||||
|
|
@ -165,10 +164,11 @@ pub fn syncback_lua<'sync>(
|
|||
.or_else(|| file_stem.strip_suffix(".legacy"))
|
||||
.unwrap_or(file_stem);
|
||||
let meta_name = if meta_name.is_empty() {
|
||||
if snapshot.encode_windows_invalid_chars() {
|
||||
encode_path_name(&new_inst.name)
|
||||
let instance_name = &new_inst.name;
|
||||
if name_needs_slugify(instance_name) {
|
||||
slugify_name(instance_name)
|
||||
} else {
|
||||
new_inst.name.clone()
|
||||
instance_name.clone()
|
||||
}
|
||||
} else {
|
||||
meta_name.to_string()
|
||||
|
|
|
|||
|
|
@ -10,7 +10,10 @@ use rbx_dom_weak::{
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
json, resolution::UnresolvedValue, snapshot::InstanceSnapshot, syncback::SyncbackSnapshot,
|
||||
json,
|
||||
resolution::UnresolvedValue,
|
||||
snapshot::InstanceSnapshot,
|
||||
syncback::{name_needs_slugify, SyncbackSnapshot},
|
||||
RojoRef,
|
||||
};
|
||||
|
||||
|
|
@ -36,6 +39,9 @@ pub struct AdjacentMetadata {
|
|||
#[serde(default, skip_serializing_if = "IndexMap::is_empty")]
|
||||
pub attributes: IndexMap<String, UnresolvedValue>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub name: Option<String>,
|
||||
|
||||
#[serde(skip)]
|
||||
pub path: PathBuf,
|
||||
}
|
||||
|
|
@ -52,9 +58,8 @@ impl AdjacentMetadata {
|
|||
_name: &str,
|
||||
snapshot: &mut InstanceSnapshot,
|
||||
) -> anyhow::Result<()> {
|
||||
// Use the file stem from the actual path (which has encoded chars)
|
||||
// rather than the decoded name, so meta files are found correctly
|
||||
// when encodeWindowsInvalidChars is enabled.
|
||||
// Use the file stem from the actual path (which may be slugified)
|
||||
// rather than the instance name, so meta files are found correctly.
|
||||
// Strip known script type suffixes to get the base name for the meta file.
|
||||
let file_stem = path.file_stem().and_then(|s| s.to_str()).unwrap_or("");
|
||||
let base_name = file_stem
|
||||
|
|
@ -156,6 +161,24 @@ impl AdjacentMetadata {
|
|||
}
|
||||
}
|
||||
|
||||
let name = snapshot
|
||||
.old_inst()
|
||||
.and_then(|inst| inst.metadata().specified_name.clone())
|
||||
.or_else(|| {
|
||||
// If this is a new instance and its name is invalid for the filesystem,
|
||||
// we need to specify the name in meta.json so it can be preserved
|
||||
if snapshot.old_inst().is_none() {
|
||||
let instance_name = &snapshot.new_inst().name;
|
||||
if name_needs_slugify(instance_name) {
|
||||
Some(instance_name.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
Ok(Some(Self {
|
||||
ignore_unknown_instances: if ignore_unknown_instances {
|
||||
Some(true)
|
||||
|
|
@ -164,6 +187,7 @@ impl AdjacentMetadata {
|
|||
},
|
||||
properties,
|
||||
attributes,
|
||||
name,
|
||||
path,
|
||||
id: None,
|
||||
schema,
|
||||
|
|
@ -225,11 +249,26 @@ impl AdjacentMetadata {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn apply_name(&mut self, snapshot: &mut InstanceSnapshot) -> anyhow::Result<()> {
|
||||
if self.name.is_some() && snapshot.metadata.specified_name.is_some() {
|
||||
anyhow::bail!(
|
||||
"cannot specify a name using {} (instance has a name from somewhere else)",
|
||||
self.path.display()
|
||||
);
|
||||
}
|
||||
if let Some(name) = &self.name {
|
||||
snapshot.name = name.clone().into();
|
||||
}
|
||||
snapshot.metadata.specified_name = self.name.take();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn apply_all(&mut self, snapshot: &mut InstanceSnapshot) -> anyhow::Result<()> {
|
||||
self.apply_ignore_unknown_instances(snapshot);
|
||||
self.apply_properties(snapshot)?;
|
||||
self.apply_id(snapshot)?;
|
||||
self.apply_schema(snapshot)?;
|
||||
self.apply_name(snapshot)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -238,11 +277,13 @@ impl AdjacentMetadata {
|
|||
///
|
||||
/// - The number of properties and attributes is 0
|
||||
/// - `ignore_unknown_instances` is None
|
||||
/// - `name` is None
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.attributes.is_empty()
|
||||
&& self.properties.is_empty()
|
||||
&& self.ignore_unknown_instances.is_none()
|
||||
&& self.name.is_none()
|
||||
}
|
||||
|
||||
// TODO: Add method to allow selectively applying parts of metadata and
|
||||
|
|
@ -274,6 +315,9 @@ pub struct DirectoryMetadata {
|
|||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub class_name: Option<Ustr>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub name: Option<String>,
|
||||
|
||||
#[serde(skip)]
|
||||
pub path: PathBuf,
|
||||
}
|
||||
|
|
@ -383,6 +427,24 @@ impl DirectoryMetadata {
|
|||
}
|
||||
}
|
||||
|
||||
let name = snapshot
|
||||
.old_inst()
|
||||
.and_then(|inst| inst.metadata().specified_name.clone())
|
||||
.or_else(|| {
|
||||
// If this is a new instance and its name is invalid for the filesystem,
|
||||
// we need to specify the name in meta.json so it can be preserved
|
||||
if snapshot.old_inst().is_none() {
|
||||
let instance_name = &snapshot.new_inst().name;
|
||||
if name_needs_slugify(instance_name) {
|
||||
Some(instance_name.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
Ok(Some(Self {
|
||||
ignore_unknown_instances: if ignore_unknown_instances {
|
||||
Some(true)
|
||||
|
|
@ -392,6 +454,7 @@ impl DirectoryMetadata {
|
|||
properties,
|
||||
attributes,
|
||||
class_name: None,
|
||||
name,
|
||||
path,
|
||||
id: None,
|
||||
schema,
|
||||
|
|
@ -404,6 +467,7 @@ impl DirectoryMetadata {
|
|||
self.apply_properties(snapshot)?;
|
||||
self.apply_id(snapshot)?;
|
||||
self.apply_schema(snapshot)?;
|
||||
self.apply_name(snapshot)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -475,17 +539,34 @@ impl DirectoryMetadata {
|
|||
snapshot.metadata.schema = self.schema.take();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn apply_name(&mut self, snapshot: &mut InstanceSnapshot) -> anyhow::Result<()> {
|
||||
if self.name.is_some() && snapshot.metadata.specified_name.is_some() {
|
||||
anyhow::bail!(
|
||||
"cannot specify a name using {} (instance has a name from somewhere else)",
|
||||
self.path.display()
|
||||
);
|
||||
}
|
||||
if let Some(name) = &self.name {
|
||||
snapshot.name = name.clone().into();
|
||||
}
|
||||
snapshot.metadata.specified_name = self.name.take();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns whether the metadata is 'empty', meaning it doesn't have anything
|
||||
/// worth persisting in it. Specifically:
|
||||
///
|
||||
/// - The number of properties and attributes is 0
|
||||
/// - `ignore_unknown_instances` is None
|
||||
/// - `class_name` is either None or not Some("Folder")
|
||||
/// - `name` is None
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.attributes.is_empty()
|
||||
&& self.properties.is_empty()
|
||||
&& self.ignore_unknown_instances.is_none()
|
||||
&& self.name.is_none()
|
||||
&& if let Some(class) = &self.class_name {
|
||||
class == "Folder"
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use crate::{
|
||||
glob::Glob,
|
||||
path_encoding::decode_path_name,
|
||||
project::DEFAULT_PROJECT_NAMES,
|
||||
syncback::{SyncbackReturn, SyncbackSnapshot},
|
||||
};
|
||||
|
|
@ -72,19 +71,17 @@ pub fn snapshot_from_vfs(
|
|||
|
||||
if meta.is_dir() {
|
||||
let (middleware, dir_name, init_path) = get_dir_middleware(vfs, path)?;
|
||||
// Decode directory name if the flag is set
|
||||
let decoded_name = if context.decode_windows_invalid_chars {
|
||||
decode_path_name(dir_name)
|
||||
} else {
|
||||
dir_name.to_string()
|
||||
};
|
||||
// The directory name is used as-is from the filesystem.
|
||||
// If a different instance name is desired, it comes from the
|
||||
// `name` field in init.meta.json / init.meta.json5 (applied later
|
||||
// by DirectoryMetadata::apply_name).
|
||||
// TODO: Support user defined init paths
|
||||
// If and when we do, make sure to go support it in
|
||||
// `Project::set_file_name`, as right now it special-cases
|
||||
// `default.project.json5` as an `init` path.
|
||||
match middleware {
|
||||
Middleware::Dir => middleware.snapshot(context, vfs, path, &decoded_name),
|
||||
_ => middleware.snapshot(context, vfs, &init_path, &decoded_name),
|
||||
Middleware::Dir => middleware.snapshot(context, vfs, path, dir_name),
|
||||
_ => middleware.snapshot(context, vfs, &init_path, dir_name),
|
||||
}
|
||||
} else {
|
||||
let file_name = path
|
||||
|
|
@ -166,23 +163,17 @@ fn snapshot_from_path(
|
|||
vfs: &Vfs,
|
||||
path: &Path,
|
||||
) -> anyhow::Result<Option<InstanceSnapshot>> {
|
||||
// Helper to decode name if the flag is set
|
||||
let decode_name = |name: &str| -> String {
|
||||
if context.decode_windows_invalid_chars {
|
||||
decode_path_name(name)
|
||||
} else {
|
||||
name.to_string()
|
||||
}
|
||||
};
|
||||
|
||||
// File names are used as-is from the filesystem. If a different instance
|
||||
// name is needed (e.g. for names with special chars), it comes from the
|
||||
// `name` field in adjacent .meta.json / .model.json files.
|
||||
if let Some(rule) = context.get_user_sync_rule(path) {
|
||||
let name = decode_name(rule.file_name_for_path(path)?);
|
||||
return rule.middleware.snapshot(context, vfs, path, &name);
|
||||
let name = rule.file_name_for_path(path)?;
|
||||
return rule.middleware.snapshot(context, vfs, path, name);
|
||||
} else {
|
||||
for rule in default_sync_rules() {
|
||||
if rule.matches(path) {
|
||||
let name = decode_name(rule.file_name_for_path(path)?);
|
||||
return rule.middleware.snapshot(context, vfs, path, &name);
|
||||
let name = rule.file_name_for_path(path)?;
|
||||
return rule.middleware.snapshot(context, vfs, path, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -647,6 +647,14 @@ pub fn syncback_project<'sync>(
|
|||
|
||||
// All of the children in this loop are by their nature not in the
|
||||
// project, so we just need to run syncback on them.
|
||||
//
|
||||
// Track taken names per parent directory so siblings under the same
|
||||
// parent deduplicate against each other (and against existing files).
|
||||
let mut taken_names_per_dir: std::collections::HashMap<
|
||||
std::path::PathBuf,
|
||||
std::collections::HashSet<String>,
|
||||
> = std::collections::HashMap::new();
|
||||
|
||||
for (name, new_child) in new_child_map.drain() {
|
||||
// Skip instances of ignored classes
|
||||
if snapshot.should_ignore_class(&new_child.class) {
|
||||
|
|
@ -680,11 +688,38 @@ pub fn syncback_project<'sync>(
|
|||
// concern with directories because they're singular things,
|
||||
// files that contain their own children.
|
||||
if parent_middleware != Middleware::Project {
|
||||
descendant_snapshots.push(snapshot.with_base_path(
|
||||
let taken_names = taken_names_per_dir
|
||||
.entry(parent_path.clone())
|
||||
.or_insert_with(|| {
|
||||
// Seed with existing files on disk so new children
|
||||
// don't collide with files already present.
|
||||
vfs.read_dir(&parent_path)
|
||||
.ok()
|
||||
.map(|entries| {
|
||||
entries
|
||||
.filter_map(|e| e.ok())
|
||||
.filter_map(|e| {
|
||||
e.path()
|
||||
.file_name()
|
||||
.and_then(|n| n.to_str())
|
||||
.map(|n| n.to_lowercase())
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_default()
|
||||
});
|
||||
let (child_snap, _needs_meta) = snapshot.with_base_path(
|
||||
&parent_path,
|
||||
new_child.referent(),
|
||||
None,
|
||||
)?);
|
||||
taken_names,
|
||||
)?;
|
||||
if let Some(file_name) =
|
||||
child_snap.path.file_name().and_then(|n| n.to_str())
|
||||
{
|
||||
taken_names.insert(file_name.to_lowercase());
|
||||
}
|
||||
descendant_snapshots.push(child_snap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- /foo.csv
|
||||
- /foo.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ metadata:
|
|||
- /root/init.server.lua
|
||||
- /root/init.client.lua
|
||||
- /root/init.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ metadata:
|
|||
- /root/init.server.lua
|
||||
- /root/init.client.lua
|
||||
- /root/init.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: manually specified
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- /foo.csv
|
||||
- /foo.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ metadata:
|
|||
- /foo/init.server.lua
|
||||
- /foo/init.client.lua
|
||||
- /foo/init.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ metadata:
|
|||
- /foo/init.server.lua
|
||||
- /foo/init.client.lua
|
||||
- /foo/init.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
@ -45,8 +44,7 @@ children:
|
|||
- /foo/Child/init.server.lua
|
||||
- /foo/Child/init.client.lua
|
||||
- /foo/Child/init.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: dir
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- /foo.json5
|
||||
- /foo.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- /foo.json5
|
||||
- /foo.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: manually specified
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ metadata:
|
|||
Path: /foo.model.json5
|
||||
relevant_paths:
|
||||
- /foo.model.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
@ -24,8 +23,7 @@ children:
|
|||
metadata:
|
||||
ignore_unknown_instances: false
|
||||
relevant_paths: []
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ metadata:
|
|||
Path: /foo.model.json5
|
||||
relevant_paths:
|
||||
- /foo.model.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
@ -24,8 +23,7 @@ children:
|
|||
metadata:
|
||||
ignore_unknown_instances: false
|
||||
relevant_paths: []
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- /foo.client.luau
|
||||
- /foo.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ metadata:
|
|||
- /root/init.server.lua
|
||||
- /root/init.client.lua
|
||||
- /root/init.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ metadata:
|
|||
- /root/init.server.lua
|
||||
- /root/init.client.lua
|
||||
- /root/init.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: manually specified
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- /foo.legacy.luau
|
||||
- /foo.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- /foo.local.luau
|
||||
- /foo.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- /foo.luau
|
||||
- /foo.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- /foo.luau
|
||||
- /foo.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- /foo.plugin.luau
|
||||
- /foo.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- /bar.server.luau
|
||||
- /bar.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- /foo.server.luau
|
||||
- /foo.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- /foo.server.luau
|
||||
- /foo.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ metadata:
|
|||
- /foo/bar.meta.json
|
||||
- /foo/bar.meta.jsonc
|
||||
- /foo/bar.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: manually specified
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@ metadata:
|
|||
ignore_unknown_instances: false
|
||||
relevant_paths:
|
||||
- /foo/bar.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: manually specified
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ metadata:
|
|||
- /foo/bar.meta.json
|
||||
- /foo/bar.meta.jsonc
|
||||
- /foo/bar.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: manually specified
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ metadata:
|
|||
- /foo/init.meta.json
|
||||
- /foo/init.meta.jsonc
|
||||
- /foo/init.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: manually specified
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@ metadata:
|
|||
ignore_unknown_instances: false
|
||||
relevant_paths:
|
||||
- /foo/init.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: manually specified
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ metadata:
|
|||
- /foo/init.meta.json
|
||||
- /foo/init.meta.jsonc
|
||||
- /foo/init.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: manually specified
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ metadata:
|
|||
Path: /foo/default.project.json5
|
||||
relevant_paths:
|
||||
- /foo/default.project.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ metadata:
|
|||
Path: /foo/hello.project.json5
|
||||
relevant_paths:
|
||||
- /foo/hello.project.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- /foo/other.project.json5
|
||||
- /foo/default.project.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: project
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ metadata:
|
|||
Path: /foo.project.json5
|
||||
relevant_paths:
|
||||
- /foo.project.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
@ -29,8 +28,7 @@ children:
|
|||
$className: Model
|
||||
parent_class: Folder
|
||||
relevant_paths: []
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- /foo/other.project.json5
|
||||
- /foo/default.project.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: project
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- /foo/other.project.json5
|
||||
- /foo/default.project.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: project
|
||||
schema: ~
|
||||
|
|
@ -30,8 +29,7 @@ children:
|
|||
$className: Model
|
||||
parent_class: Folder
|
||||
relevant_paths: []
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -11,8 +11,7 @@ metadata:
|
|||
- /foo/other.txt
|
||||
- /foo/other.meta.json5
|
||||
- /foo/default.project.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: text
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ metadata:
|
|||
Path: /foo.project.json5
|
||||
relevant_paths:
|
||||
- /foo.project.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ metadata:
|
|||
Path: /foo.project.json5
|
||||
relevant_paths:
|
||||
- /foo.project.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- /foo.toml
|
||||
- /foo.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- foo.toml
|
||||
- foo.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: manually specified
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- /foo.txt
|
||||
- /foo.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- /foo.txt
|
||||
- /foo.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: manually specified
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- /foo.yaml
|
||||
- /foo.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: ~
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ metadata:
|
|||
relevant_paths:
|
||||
- foo.yaml
|
||||
- foo.meta.json5
|
||||
context:
|
||||
decode_windows_invalid_chars: true
|
||||
context: {}
|
||||
specified_id: manually specified
|
||||
middleware: ~
|
||||
schema: ~
|
||||
|
|
|
|||
|
|
@ -6,9 +6,8 @@ use rbx_dom_weak::types::Variant;
|
|||
use rbx_dom_weak::ustr;
|
||||
|
||||
use crate::{
|
||||
path_encoding::encode_path_name,
|
||||
snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot},
|
||||
syncback::{FsSnapshot, SyncbackReturn, SyncbackSnapshot},
|
||||
syncback::{name_needs_slugify, slugify_name, FsSnapshot, SyncbackReturn, SyncbackSnapshot},
|
||||
};
|
||||
|
||||
use super::{meta_file::AdjacentMetadata, PathExt as _};
|
||||
|
|
@ -59,10 +58,11 @@ pub fn syncback_txt<'sync>(
|
|||
|
||||
if !meta.is_empty() {
|
||||
let parent = snapshot.path.parent_err()?;
|
||||
let meta_name = if snapshot.encode_windows_invalid_chars() {
|
||||
encode_path_name(&new_inst.name)
|
||||
let instance_name = &new_inst.name;
|
||||
let meta_name = if name_needs_slugify(instance_name) {
|
||||
slugify_name(instance_name)
|
||||
} else {
|
||||
new_inst.name.clone()
|
||||
instance_name.clone()
|
||||
};
|
||||
fs_snapshot.add_file(
|
||||
parent.join(format!("{}.meta.json5", meta_name)),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue