Add back legacy support for .json and .lua

This commit is contained in:
Joe 2026-01-30 09:38:43 -06:00
parent 4aac7d0d48
commit 5f059dbc16
10 changed files with 95 additions and 18 deletions

View file

@ -16,7 +16,8 @@ use crate::{
};
/// Represents 'default' project names that act as `init` files
pub static DEFAULT_PROJECT_NAMES: [&str; 1] = ["default.project.json5"];
/// Includes legacy `.json` extension as fallback for backwards compatibility.
pub static DEFAULT_PROJECT_NAMES: [&str; 2] = ["default.project.json5", "default.project.json"];
/// Error type returned by any function that handles projects.
#[derive(Debug, Error)]
@ -140,7 +141,7 @@ impl Project {
pub fn is_project_file(path: &Path) -> bool {
path.file_name()
.and_then(|name| name.to_str())
.map(|name| name.ends_with(".project.json5"))
.map(|name| name.ends_with(".project.json5") || name.ends_with(".project.json"))
.unwrap_or(false)
}

View file

@ -68,12 +68,17 @@ pub fn snapshot_dir_no_meta(
// TODO: We shouldn't need to know about Lua existing in this
// middleware. Should we figure out a way for that function to add
// relevant paths to this middleware?
// Modern extensions (preferred)
normalized_path.join("init.luau"),
normalized_path.join("init.server.luau"),
normalized_path.join("init.client.luau"),
normalized_path.join("init.local.luau"),
normalized_path.join("init.legacy.luau"),
normalized_path.join("init.csv"),
// Legacy extensions (for backwards compatibility)
normalized_path.join("init.lua"),
normalized_path.join("init.server.lua"),
normalized_path.join("init.client.lua"),
];
let snapshot = InstanceSnapshot::new()

View file

@ -64,15 +64,22 @@ impl AdjacentMetadata {
.or_else(|| file_stem.strip_suffix(".local"))
.or_else(|| file_stem.strip_suffix(".legacy"))
.unwrap_or(file_stem);
let meta_path = path.with_file_name(format!("{base_name}.meta.json5"));
// Try modern extension first, then fall back to legacy
let meta_path_json5 = path.with_file_name(format!("{base_name}.meta.json5"));
let meta_path_json = path.with_file_name(format!("{base_name}.meta.json"));
if let Some(meta_contents) = vfs.read(&meta_path).with_not_found()? {
let mut metadata = Self::from_slice(&meta_contents, meta_path.clone())?;
if let Some(meta_contents) = vfs.read(&meta_path_json5).with_not_found()? {
let mut metadata = Self::from_slice(&meta_contents, meta_path_json5.clone())?;
metadata.apply_all(snapshot)?;
} else if let Some(meta_contents) = vfs.read(&meta_path_json).with_not_found()? {
// Legacy fallback: .meta.json
let mut metadata = Self::from_slice(&meta_contents, meta_path_json.clone())?;
metadata.apply_all(snapshot)?;
}
// Rather than pushing these in the snapshot middleware, we can just do it here.
snapshot.metadata.relevant_paths.push(meta_path);
snapshot.metadata.relevant_paths.push(meta_path_json5);
Ok(())
}
@ -282,15 +289,21 @@ impl DirectoryMetadata {
path: &Path,
snapshot: &mut InstanceSnapshot,
) -> anyhow::Result<()> {
let meta_path = path.join("init.meta.json5");
// Try modern extension first, then fall back to legacy
let meta_path_json5 = path.join("init.meta.json5");
let meta_path_json = path.join("init.meta.json");
if let Some(meta_contents) = vfs.read(&meta_path).with_not_found()? {
let mut metadata = Self::from_slice(&meta_contents, meta_path.clone())?;
if let Some(meta_contents) = vfs.read(&meta_path_json5).with_not_found()? {
let mut metadata = Self::from_slice(&meta_contents, meta_path_json5.clone())?;
metadata.apply_all(snapshot)?;
} else if let Some(meta_contents) = vfs.read(&meta_path_json).with_not_found()? {
// Legacy fallback: init.meta.json
let mut metadata = Self::from_slice(&meta_contents, meta_path_json.clone())?;
metadata.apply_all(snapshot)?;
}
// Rather than pushing these in the snapshot middleware, we can just do it here.
snapshot.metadata.relevant_paths.push(meta_path);
snapshot.metadata.relevant_paths.push(meta_path_json5);
Ok(())
}
@ -484,11 +497,20 @@ impl DirectoryMetadata {
/// Retrieves the meta file that should be applied for the provided directory,
/// if it exists.
pub fn dir_meta(vfs: &Vfs, path: &Path) -> anyhow::Result<Option<DirectoryMetadata>> {
let meta_path = path.join("init.meta.json5");
if let Some(meta_contents) = vfs.read(&meta_path).with_not_found()? {
let metadata = DirectoryMetadata::from_slice(&meta_contents, meta_path)?;
// Try modern extension first, then fall back to legacy
let meta_path_json5 = path.join("init.meta.json5");
if let Some(meta_contents) = vfs.read(&meta_path_json5).with_not_found()? {
let metadata = DirectoryMetadata::from_slice(&meta_contents, meta_path_json5)?;
return Ok(Some(metadata));
}
// Legacy fallback: init.meta.json
let meta_path_json = path.join("init.meta.json");
if let Some(meta_contents) = vfs.read(&meta_path_json).with_not_found()? {
let metadata = DirectoryMetadata::from_slice(&meta_contents, meta_path_json)?;
return Ok(Some(metadata));
}
Ok(None)
}
@ -497,12 +519,22 @@ pub fn dir_meta(vfs: &Vfs, path: &Path) -> anyhow::Result<Option<DirectoryMetada
///
/// The `name` field should be the name the metadata should have.
pub fn file_meta(vfs: &Vfs, path: &Path, name: &str) -> anyhow::Result<Option<AdjacentMetadata>> {
let mut meta_path = path.with_file_name(name);
meta_path.set_extension("meta.json5");
if let Some(meta_contents) = vfs.read(&meta_path).with_not_found()? {
let metadata = AdjacentMetadata::from_slice(&meta_contents, meta_path)?;
// Try modern extension first, then fall back to legacy
let mut meta_path_json5 = path.with_file_name(name);
meta_path_json5.set_extension("meta.json5");
if let Some(meta_contents) = vfs.read(&meta_path_json5).with_not_found()? {
let metadata = AdjacentMetadata::from_slice(&meta_contents, meta_path_json5)?;
return Ok(Some(metadata));
}
// Legacy fallback: .meta.json
let mut meta_path_json = path.with_file_name(name);
meta_path_json.set_extension("meta.json");
if let Some(meta_contents) = vfs.read(&meta_path_json).with_not_found()? {
let metadata = AdjacentMetadata::from_slice(&meta_contents, meta_path_json)?;
return Ok(Some(metadata));
}
Ok(None)
}

View file

@ -94,8 +94,11 @@ pub fn snapshot_from_vfs(
// TODO: Is this even necessary anymore?
match file_name {
// Modern extensions
"init.server.luau" | "init.client.luau" | "init.local.luau" | "init.legacy.luau"
| "init.luau" | "init.csv" => return Ok(None),
| "init.luau" | "init.csv" |
// Legacy extensions (for backwards compatibility)
"init.server.lua" | "init.client.lua" | "init.lua" => return Ok(None),
_ => {}
}
@ -122,12 +125,17 @@ fn get_dir_middleware<'path>(
static INIT_PATHS: OnceLock<Vec<(Middleware, &str)>> = OnceLock::new();
let order = INIT_PATHS.get_or_init(|| {
vec![
// Modern extensions (preferred)
(Middleware::ModuleScriptDir, "init.luau"),
(Middleware::ServerScriptDir, "init.server.luau"),
(Middleware::ClientScriptDir, "init.client.luau"),
(Middleware::LocalScriptDir, "init.local.luau"),
(Middleware::LegacyScriptDir, "init.legacy.luau"),
(Middleware::CsvDir, "init.csv"),
// Legacy extensions (for backwards compatibility)
(Middleware::ModuleScriptDir, "init.lua"),
(Middleware::ServerScriptDir, "init.server.lua"),
(Middleware::ClientScriptDir, "init.client.lua"),
]
});
@ -412,6 +420,7 @@ pub fn default_sync_rules() -> &'static [SyncRule] {
DEFAULT_SYNC_RULES.get_or_init(|| {
vec![
// Modern extensions (preferred)
sync_rule!("*.server.luau", ServerScript, ".server.luau"),
sync_rule!("*.client.luau", ClientScript, ".client.luau"),
sync_rule!("*.plugin.luau", PluginScript, ".plugin.luau"),
@ -421,6 +430,15 @@ pub fn default_sync_rules() -> &'static [SyncRule] {
sync_rule!("*.project.json5", Project, ".project.json5"),
sync_rule!("*.model.json5", JsonModel, ".model.json5"),
sync_rule!("*.json5", Json, ".json5", "*.meta.json5"),
// Legacy Lua extensions (for backwards compatibility)
sync_rule!("*.server.lua", ServerScript, ".server.lua"),
sync_rule!("*.client.lua", ClientScript, ".client.lua"),
sync_rule!("*.lua", ModuleScript),
// Legacy JSON extensions (for backwards compatibility)
sync_rule!("*.project.json", Project, ".project.json"),
sync_rule!("*.model.json", JsonModel, ".model.json"),
sync_rule!("*.json", Json, ".json", "*.meta.json"),
// Other formats
sync_rule!("*.toml", Toml),
sync_rule!("*.csv", Csv),
sync_rule!("*.txt", Text),

View file

@ -15,6 +15,9 @@ metadata:
- /root/init.local.luau
- /root/init.legacy.luau
- /root/init.csv
- /root/init.lua
- /root/init.server.lua
- /root/init.client.lua
- /root/init.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -15,6 +15,9 @@ metadata:
- /root/init.local.luau
- /root/init.legacy.luau
- /root/init.csv
- /root/init.lua
- /root/init.server.lua
- /root/init.client.lua
- /root/init.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -15,6 +15,9 @@ metadata:
- /foo/init.local.luau
- /foo/init.legacy.luau
- /foo/init.csv
- /foo/init.lua
- /foo/init.server.lua
- /foo/init.client.lua
- /foo/init.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -15,6 +15,9 @@ metadata:
- /foo/init.local.luau
- /foo/init.legacy.luau
- /foo/init.csv
- /foo/init.lua
- /foo/init.server.lua
- /foo/init.client.lua
- /foo/init.meta.json5
context:
decode_windows_invalid_chars: true
@ -38,6 +41,9 @@ children:
- /foo/Child/init.local.luau
- /foo/Child/init.legacy.luau
- /foo/Child/init.csv
- /foo/Child/init.lua
- /foo/Child/init.server.lua
- /foo/Child/init.client.lua
- /foo/Child/init.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -15,6 +15,9 @@ metadata:
- /root/init.local.luau
- /root/init.legacy.luau
- /root/init.csv
- /root/init.lua
- /root/init.server.lua
- /root/init.client.lua
- /root/init.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -15,6 +15,9 @@ metadata:
- /root/init.local.luau
- /root/init.legacy.luau
- /root/init.csv
- /root/init.lua
- /root/init.server.lua
- /root/init.client.lua
- /root/init.meta.json5
context:
decode_windows_invalid_chars: true