Update project configuration and snapshot files

- Changed the default project file from `plugin.project.json` to `plugin.project.json5` in `build.rs`.
- Added new project configuration files in JSON5 format for various test cases, including `default.project.json5`, `client_in_folder`, `csv_bug_145`, and others.
- Updated snapshot files to reflect changes in instance structure and properties, ensuring consistency with the new project configurations.
- Removed unnecessary script and module instances from snapshot files to streamline the testing process.
This commit is contained in:
Joe 2026-01-30 08:32:42 -06:00
parent d3cc11659a
commit 779e3de0ae
216 changed files with 350 additions and 514 deletions

View file

@ -16,11 +16,7 @@ use crate::{
};
/// Represents 'default' project names that act as `init` files
pub static DEFAULT_PROJECT_NAMES: [&str; 3] = [
"default.project.json",
"default.project.jsonc",
"default.project.json5",
];
pub static DEFAULT_PROJECT_NAMES: [&str; 1] = ["default.project.json5"];
/// Error type returned by any function that handles projects.
#[derive(Debug, Error)]
@ -60,7 +56,7 @@ enum Error {
/// Contains all of the configuration for a Rojo-managed project.
///
/// Project files are stored in `.project.json` files.
/// Project files are stored in `.project.json5` files.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub struct Project {
@ -144,18 +140,14 @@ 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.json")
|| name.ends_with(".project.jsonc")
|| name.ends_with(".project.json5")
})
.map(|name| name.ends_with(".project.json5"))
.unwrap_or(false)
}
/// Attempt to locate a project represented by the given path.
///
/// This will find a project if the path refers to a `.project.json` file,
/// or is a folder that contains a `default.project.json` file.
/// This will find a project if the path refers to a `.project.json5` file,
/// or is a folder that contains a `default.project.json5` file.
fn locate(path: &Path) -> Option<PathBuf> {
let meta = fs::metadata(path).ok()?;
@ -184,7 +176,7 @@ impl Project {
/// Sets the name of a project. The order it handles is as follows:
///
/// - If the project is a `default.project.json`, uses the folder's name
/// - If the project is a `default.project.json5`, uses the folder's name
/// - If a fallback is specified, uses that blindly
/// - Otherwise, loops through sync rules (including the default ones!) and
/// uses the name of the first one that matches and is a project file
@ -222,7 +214,7 @@ impl Project {
// If you're adding this codepath, make sure a test for it exists
// and that it handles sync rules appropriately.
todo!(
"set_file_name doesn't support loading project files that aren't default.project.json without a fallback provided"
"set_file_name doesn't support loading project files that aren't default.project.json5 without a fallback provided"
);
}
@ -250,8 +242,8 @@ impl Project {
}
/// Loads a Project from a path. This will find the project if it refers to
/// a `.project.json` file or if it refers to a directory that contains a
/// file named `default.project.json`.
/// a `.project.json5` file or if it refers to a directory that contains a
/// file named `default.project.json5`.
pub fn load_fuzzy(
vfs: &Vfs,
fuzzy_project_location: &Path,
@ -421,8 +413,8 @@ pub struct ProjectNode {
pub ignore_unknown_instances: Option<bool>,
/// Defines that this instance should come from the given file path. This
/// path can point to any file type supported by Rojo, including Lua files
/// (`.lua`), Roblox models (`.rbxm`, `.rbxmx`), and localization table
/// path can point to any file type supported by Rojo, including Luau files
/// (`.luau`), Roblox models (`.rbxm`, `.rbxmx`), and localization table
/// spreadsheets (`.csv`).
#[serde(rename = "$path", skip_serializing_if = "Option::is_none")]
pub path: Option<PathNode>,
@ -569,16 +561,16 @@ mod test {
"servePort": 34567,
// Test glob parsing with comments
"globIgnorePaths": [
"**/*.spec.lua", // Ignore test files
"**/*.test.lua",
"**/*.spec.luau", // Ignore test files
"**/*.test.luau",
],
"syncRules": [
{
"pattern": "*.data.json",
"pattern": "*.data.json5",
"use": "json", // Trailing comma in object
},
{
"pattern": "*.module.lua",
"pattern": "*.module.luau",
"use": "moduleScript",
}, // Trailing comma in array
], // Another trailing comma
@ -586,7 +578,7 @@ mod test {
let project = Project::load_from_slice(
project_json.as_bytes(),
PathBuf::from("/test/default.project.jsonc"),
PathBuf::from("/test/default.project.json5"),
None,
)
.expect("Failed to parse project with JSONC features");
@ -597,12 +589,12 @@ mod test {
// Verify glob_ignore_paths were parsed correctly
assert_eq!(project.glob_ignore_paths.len(), 2);
assert!(project.glob_ignore_paths[0].is_match("test/foo.spec.lua"));
assert!(project.glob_ignore_paths[1].is_match("test/bar.test.lua"));
assert!(project.glob_ignore_paths[0].is_match("test/foo.spec.luau"));
assert!(project.glob_ignore_paths[1].is_match("test/bar.test.luau"));
// Verify sync_rules were parsed correctly
assert_eq!(project.sync_rules.len(), 2);
assert!(project.sync_rules[0].include.is_match("data.data.json"));
assert!(project.sync_rules[1].include.is_match("init.module.lua"));
assert!(project.sync_rules[0].include.is_match("data.data.json5"));
assert!(project.sync_rules[1].include.is_match("init.module.luau"));
}
}

View file

@ -53,9 +53,9 @@ pub struct ServeSession {
/// The root project for the serve session.
///
/// This will be defined if a folder with a `default.project.json` file was
/// This will be defined if a folder with a `default.project.json5` file was
/// used for starting the serve session, or if the user specified a full
/// path to a `.project.json` file.
/// path to a `.project.json5` file.
root_project: Project,
/// A randomly generated ID for this serve session. It's used to ensure that

View file

@ -30,9 +30,9 @@ pub struct InstanceMetadata {
/// even if they don't exist, since the presence of a file can change the
/// outcome of a snapshot function.
///
/// For example, a file named foo.lua might have these relevant paths:
/// - foo.lua
/// - foo.meta.json (even if this file doesn't exist!)
/// For example, a file named foo.luau might have these relevant paths:
/// - foo.luau
/// - foo.meta.json5 (even if this file doesn't exist!)
///
/// A directory named bar/ might have these:
/// - bar/

View file

@ -345,7 +345,7 @@ Ack,Ack!,,An exclamation of despair,¡Ay!"#,
)
.unwrap();
imfs.load_snapshot(
"/foo.meta.json",
"/foo.meta.json5",
VfsSnapshot::file(r#"{ "ignoreUnknownInstances": true }"#),
)
.unwrap();
@ -411,7 +411,7 @@ Ack,Ack!,,An exclamation of despair,¡Ay!"#,
),
),
(
"init.meta.json",
"init.meta.json5",
VfsSnapshot::file(r#"{"id": "manually specified"}"#),
),
]),

View file

@ -122,7 +122,7 @@ mod test {
)
.unwrap();
imfs.load_snapshot(
"/foo.meta.json",
"/foo.meta.json5",
VfsSnapshot::file(
r#"{
"id": "manually specified"

View file

@ -238,7 +238,7 @@ mod test {
#[test]
fn module_from_vfs() {
let mut imfs = InMemoryFs::new();
imfs.load_snapshot("/foo.lua", VfsSnapshot::file("Hello there!"))
imfs.load_snapshot("/foo.luau", VfsSnapshot::file("Hello there!"))
.unwrap();
let vfs = Vfs::new(imfs);
@ -246,7 +246,7 @@ mod test {
let instance_snapshot = snapshot_lua(
&InstanceContext::new(),
&vfs,
Path::new("/foo.lua"),
Path::new("/foo.luau"),
"foo",
ScriptType::Module,
)
@ -261,7 +261,7 @@ mod test {
#[test]
fn plugin_from_vfs() {
let mut imfs = InMemoryFs::new();
imfs.load_snapshot("/foo.plugin.lua", VfsSnapshot::file("Hello there!"))
imfs.load_snapshot("/foo.plugin.luau", VfsSnapshot::file("Hello there!"))
.unwrap();
let vfs = Vfs::new(imfs);
@ -269,7 +269,7 @@ mod test {
let instance_snapshot = snapshot_lua(
&InstanceContext::new(),
&vfs,
Path::new("/foo.plugin.lua"),
Path::new("/foo.plugin.luau"),
"foo",
ScriptType::Plugin,
)
@ -284,7 +284,7 @@ mod test {
#[test]
fn server_from_vfs() {
let mut imfs = InMemoryFs::new();
imfs.load_snapshot("/foo.server.lua", VfsSnapshot::file("Hello there!"))
imfs.load_snapshot("/foo.server.luau", VfsSnapshot::file("Hello there!"))
.unwrap();
let vfs = Vfs::new(imfs);
@ -292,7 +292,7 @@ mod test {
let instance_snapshot = snapshot_lua(
&InstanceContext::new(),
&vfs,
Path::new("/foo.server.lua"),
Path::new("/foo.server.luau"),
"foo",
ScriptType::Server,
)
@ -307,7 +307,7 @@ mod test {
#[test]
fn client_from_vfs() {
let mut imfs = InMemoryFs::new();
imfs.load_snapshot("/foo.client.lua", VfsSnapshot::file("Hello there!"))
imfs.load_snapshot("/foo.client.luau", VfsSnapshot::file("Hello there!"))
.unwrap();
let vfs = Vfs::new(imfs);
@ -315,7 +315,7 @@ mod test {
let instance_snapshot = snapshot_lua(
&InstanceContext::new(),
&vfs,
Path::new("/foo.client.lua"),
Path::new("/foo.client.luau"),
"foo",
ScriptType::Client,
)
@ -330,7 +330,7 @@ mod test {
#[test]
fn local_from_vfs() {
let mut imfs = InMemoryFs::new();
imfs.load_snapshot("/foo.local.lua", VfsSnapshot::file("Hello there!"))
imfs.load_snapshot("/foo.local.luau", VfsSnapshot::file("Hello there!"))
.unwrap();
let vfs = Vfs::new(imfs);
@ -338,7 +338,7 @@ mod test {
let instance_snapshot = snapshot_lua(
&InstanceContext::new(),
&vfs,
Path::new("/foo.local.lua"),
Path::new("/foo.local.luau"),
"foo",
ScriptType::Local,
)
@ -353,7 +353,7 @@ mod test {
#[test]
fn legacy_from_vfs() {
let mut imfs = InMemoryFs::new();
imfs.load_snapshot("/foo.legacy.lua", VfsSnapshot::file("Hello there!"))
imfs.load_snapshot("/foo.legacy.luau", VfsSnapshot::file("Hello there!"))
.unwrap();
let vfs = Vfs::new(imfs);
@ -361,7 +361,7 @@ mod test {
let instance_snapshot = snapshot_lua(
&InstanceContext::new(),
&vfs,
Path::new("/foo.legacy.lua"),
Path::new("/foo.legacy.luau"),
"foo",
ScriptType::Legacy,
)
@ -378,7 +378,7 @@ mod test {
let mut imfs = InMemoryFs::new();
imfs.load_snapshot(
"/root",
VfsSnapshot::dir([("init.lua", VfsSnapshot::file("Hello!"))]),
VfsSnapshot::dir([("init.luau", VfsSnapshot::file("Hello!"))]),
)
.unwrap();
@ -387,7 +387,7 @@ mod test {
let instance_snapshot = snapshot_lua_init(
&InstanceContext::new(),
&vfs,
Path::new("/root/init.lua"),
Path::new("/root/init.luau"),
"root",
ScriptType::Module,
)
@ -405,9 +405,9 @@ mod test {
imfs.load_snapshot(
"/root",
VfsSnapshot::dir([
("init.lua", VfsSnapshot::file("Hello!")),
("init.luau", VfsSnapshot::file("Hello!")),
(
"init.meta.json",
"init.meta.json5",
VfsSnapshot::file(r#"{"id": "manually specified"}"#),
),
]),
@ -419,7 +419,7 @@ mod test {
let instance_snapshot = snapshot_lua_init(
&InstanceContext::new(),
&vfs,
Path::new("/root/init.lua"),
Path::new("/root/init.luau"),
"root",
ScriptType::Module,
)
@ -434,10 +434,10 @@ mod test {
#[test]
fn module_with_meta() {
let mut imfs = InMemoryFs::new();
imfs.load_snapshot("/foo.lua", VfsSnapshot::file("Hello there!"))
imfs.load_snapshot("/foo.luau", VfsSnapshot::file("Hello there!"))
.unwrap();
imfs.load_snapshot(
"/foo.meta.json",
"/foo.meta.json5",
VfsSnapshot::file(
r#"
{
@ -453,7 +453,7 @@ mod test {
let instance_snapshot = snapshot_lua(
&InstanceContext::new(),
&vfs,
Path::new("/foo.lua"),
Path::new("/foo.luau"),
"foo",
ScriptType::Module,
)
@ -468,10 +468,10 @@ mod test {
#[test]
fn server_with_meta() {
let mut imfs = InMemoryFs::new();
imfs.load_snapshot("/foo.server.lua", VfsSnapshot::file("Hello there!"))
imfs.load_snapshot("/foo.server.luau", VfsSnapshot::file("Hello there!"))
.unwrap();
imfs.load_snapshot(
"/foo.meta.json",
"/foo.meta.json5",
VfsSnapshot::file(
r#"
{
@ -487,7 +487,7 @@ mod test {
let instance_snapshot = snapshot_lua(
&InstanceContext::new(),
&vfs,
Path::new("/foo.server.lua"),
Path::new("/foo.server.luau"),
"foo",
ScriptType::Server,
)
@ -502,10 +502,10 @@ mod test {
#[test]
fn server_disabled() {
let mut imfs = InMemoryFs::new();
imfs.load_snapshot("/bar.server.lua", VfsSnapshot::file("Hello there!"))
imfs.load_snapshot("/bar.server.luau", VfsSnapshot::file("Hello there!"))
.unwrap();
imfs.load_snapshot(
"/bar.meta.json",
"/bar.meta.json5",
VfsSnapshot::file(
r#"
{
@ -523,7 +523,7 @@ mod test {
let instance_snapshot = snapshot_lua(
&InstanceContext::new(),
&vfs,
Path::new("/bar.server.lua"),
Path::new("/bar.server.luau"),
"bar",
ScriptType::Server,
)

View file

@ -16,8 +16,8 @@ use crate::{
/// Represents metadata in a sibling file with the same basename.
///
/// As an example, hello.meta.json next to hello.lua would allow assigning
/// additional metadata to the instance resulting from hello.lua.
/// As an example, hello.meta.json5 next to hello.luau would allow assigning
/// additional metadata to the instance resulting from hello.luau.
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AdjacentMetadata {
@ -64,29 +64,15 @@ impl AdjacentMetadata {
.or_else(|| file_stem.strip_suffix(".local"))
.or_else(|| file_stem.strip_suffix(".legacy"))
.unwrap_or(file_stem);
let meta_path_json = path.with_file_name(format!("{base_name}.meta.json"));
let meta_path_jsonc = path.with_file_name(format!("{base_name}.meta.jsonc"));
let meta_path_json5 = path.with_file_name(format!("{base_name}.meta.json5"));
let meta_path = path.with_file_name(format!("{base_name}.meta.json5"));
if let Some(meta_contents) = vfs.read(&meta_path_json).with_not_found()? {
let mut metadata = Self::from_slice(&meta_contents, meta_path_json.clone())?;
metadata.apply_all(snapshot)?;
}
if let Some(meta_contents) = vfs.read(&meta_path_jsonc).with_not_found()? {
let mut metadata = Self::from_slice(&meta_contents, meta_path_jsonc.clone())?;
metadata.apply_all(snapshot)?;
}
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())?;
if let Some(meta_contents) = vfs.read(&meta_path).with_not_found()? {
let mut metadata = Self::from_slice(&meta_contents, meta_path.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_json);
snapshot.metadata.relevant_paths.push(meta_path_jsonc);
snapshot.metadata.relevant_paths.push(meta_path_json5);
snapshot.metadata.relevant_paths.push(meta_path);
Ok(())
}
@ -94,7 +80,7 @@ impl AdjacentMetadata {
fn from_slice(slice: &[u8], path: PathBuf) -> anyhow::Result<Self> {
let mut meta: Self = json::from_slice_with_context(slice, || {
format!(
"File contained malformed .meta.json data: {}",
"File contained malformed .meta.json5 data: {}",
path.display()
)
})?;
@ -259,7 +245,7 @@ impl AdjacentMetadata {
/// Represents metadata that affects the instance resulting from the containing
/// folder.
///
/// This is always sourced from a file named init.meta.json.
/// This is always sourced from a file named init.meta.json5.
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DirectoryMetadata {
@ -286,7 +272,7 @@ pub struct DirectoryMetadata {
}
impl DirectoryMetadata {
/// Attempts to read an `init.meta`` file for the provided path, and if
/// Attempts to read an `init.meta.json5` file for the provided path, and if
/// one exists applies it.
///
/// Also inserts the potential metadata paths into the snapshot's relevant
@ -296,29 +282,15 @@ impl DirectoryMetadata {
path: &Path,
snapshot: &mut InstanceSnapshot,
) -> anyhow::Result<()> {
let meta_path_json = path.join("init.meta.json");
let meta_path_jsonc = path.join("init.meta.jsonc");
let meta_path_json5 = path.join("init.meta.json5");
let meta_path = path.join("init.meta.json5");
if let Some(meta_contents) = vfs.read(&meta_path_json).with_not_found()? {
let mut metadata = Self::from_slice(&meta_contents, meta_path_json.clone())?;
metadata.apply_all(snapshot)?;
}
if let Some(meta_contents) = vfs.read(&meta_path_jsonc).with_not_found()? {
let mut metadata = Self::from_slice(&meta_contents, meta_path_jsonc.clone())?;
metadata.apply_all(snapshot)?;
}
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())?;
if let Some(meta_contents) = vfs.read(&meta_path).with_not_found()? {
let mut metadata = Self::from_slice(&meta_contents, meta_path.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_json);
snapshot.metadata.relevant_paths.push(meta_path_jsonc);
snapshot.metadata.relevant_paths.push(meta_path_json5);
snapshot.metadata.relevant_paths.push(meta_path);
Ok(())
}
@ -326,7 +298,7 @@ impl DirectoryMetadata {
fn from_slice(slice: &[u8], path: PathBuf) -> anyhow::Result<Self> {
let mut meta: Self = json::from_slice_with_context(slice, || {
format!(
"File contained malformed init.meta.json data: {}",
"File contained malformed init.meta.json5 data: {}",
path.display()
)
})?;
@ -428,7 +400,7 @@ impl DirectoryMetadata {
if snapshot.class_name != "Folder" {
// TODO: Turn into error type
return Err(format_err!(
"className in init.meta.json can only be specified if the \
"className in init.meta.json5 can only be specified if the \
affected directory would turn into a Folder instance."
));
}
@ -510,32 +482,26 @@ impl DirectoryMetadata {
}
/// Retrieves the meta file that should be applied for the provided directory,
/// if it exists. Checks for .json5, .jsonc, and .json in that order.
/// if it exists.
pub fn dir_meta(vfs: &Vfs, path: &Path) -> anyhow::Result<Option<DirectoryMetadata>> {
// Check json5 first (preferred), then jsonc, then json
for ext in ["init.meta.json5", "init.meta.jsonc", "init.meta.json"] {
let meta_path = path.join(ext);
if let Some(meta_contents) = vfs.read(&meta_path).with_not_found()? {
let metadata = DirectoryMetadata::from_slice(&meta_contents, meta_path)?;
return Ok(Some(metadata));
}
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)?;
return Ok(Some(metadata));
}
Ok(None)
}
/// Retrieves the meta file that should be applied for the provided file,
/// if it exists. Checks for .json5, .jsonc, and .json in that order.
/// if it exists.
///
/// 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>> {
// Check json5 first (preferred), then jsonc, then json
for ext in ["meta.json5", "meta.jsonc", "meta.json"] {
let mut meta_path = path.with_file_name(name);
meta_path.set_extension(ext);
if let Some(meta_contents) = vfs.read(&meta_path).with_not_found()? {
let metadata = AdjacentMetadata::from_slice(&meta_contents, meta_path)?;
return Ok(Some(metadata));
}
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)?;
return Ok(Some(metadata));
}
Ok(None)
}
@ -547,10 +513,10 @@ mod test {
use super::*;
#[test]
fn adjacent_read_json() {
fn adjacent_read_json5() {
let mut imfs = InMemoryFs::new();
imfs.load_snapshot(
"/foo/bar.meta.json",
"/foo/bar.meta.json5",
VfsSnapshot::file(r#"{"id": "manually specified"}"#),
)
.unwrap();
@ -565,46 +531,10 @@ mod test {
}
#[test]
fn adjacent_read_jsonc() {
fn directory_read_json5() {
let mut imfs = InMemoryFs::new();
imfs.load_snapshot(
"/foo/bar.meta.jsonc",
VfsSnapshot::file(r#"{"id": "manually specified"}"#),
)
.unwrap();
let vfs = Vfs::new(imfs);
let path = Path::new("/foo/bar.rojo");
let mut snapshot = InstanceSnapshot::new();
AdjacentMetadata::read_and_apply_all(&vfs, path, "bar", &mut snapshot).unwrap();
insta::assert_yaml_snapshot!(snapshot);
}
#[test]
fn directory_read_json() {
let mut imfs = InMemoryFs::new();
imfs.load_snapshot(
"/foo/init.meta.json",
VfsSnapshot::file(r#"{"id": "manually specified"}"#),
)
.unwrap();
let vfs = Vfs::new(imfs);
let path = Path::new("/foo/");
let mut snapshot = InstanceSnapshot::new();
DirectoryMetadata::read_and_apply_all(&vfs, path, &mut snapshot).unwrap();
insta::assert_yaml_snapshot!(snapshot);
}
#[test]
fn directory_read_jsonc() {
let mut imfs = InMemoryFs::new();
imfs.load_snapshot(
"/foo/init.meta.jsonc",
"/foo/init.meta.json5",
VfsSnapshot::file(r#"{"id": "manually specified"}"#),
)
.unwrap();

View file

@ -81,7 +81,7 @@ pub fn snapshot_from_vfs(
// 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.json` as an `init` path.
// `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),
@ -94,9 +94,8 @@ pub fn snapshot_from_vfs(
// TODO: Is this even necessary anymore?
match file_name {
"init.server.luau" | "init.server.lua" | "init.client.luau" | "init.client.lua"
| "init.local.luau" | "init.local.lua" | "init.legacy.luau" | "init.legacy.lua"
| "init.luau" | "init.lua" | "init.csv" => return Ok(None),
"init.server.luau" | "init.client.luau" | "init.local.luau" | "init.legacy.luau"
| "init.luau" | "init.csv" => return Ok(None),
_ => {}
}
@ -124,15 +123,10 @@ fn get_dir_middleware<'path>(
let order = INIT_PATHS.get_or_init(|| {
vec![
(Middleware::ModuleScriptDir, "init.luau"),
(Middleware::ModuleScriptDir, "init.lua"),
(Middleware::ServerScriptDir, "init.server.luau"),
(Middleware::ServerScriptDir, "init.server.lua"),
(Middleware::ClientScriptDir, "init.client.luau"),
(Middleware::ClientScriptDir, "init.client.lua"),
(Middleware::LocalScriptDir, "init.local.luau"),
(Middleware::LocalScriptDir, "init.local.lua"),
(Middleware::LegacyScriptDir, "init.legacy.luau"),
(Middleware::LegacyScriptDir, "init.legacy.lua"),
(Middleware::CsvDir, "init.csv"),
]
});
@ -333,10 +327,10 @@ impl Middleware {
/// Returns whether this particular middleware sets its own properties.
/// This applies to things like `JsonModel` and `Project`, since they
/// set properties without needing a meta.json file.
/// set properties without needing a meta.json5 file.
///
/// It does not cover middleware like `ServerScript` or `Csv` because they
/// need a meta.json file to set properties that aren't their designated
/// need a meta.json5 file to set properties that aren't their designated
/// 'special' properties.
#[inline]
pub fn handles_own_properties(&self) -> bool {
@ -418,25 +412,14 @@ pub fn default_sync_rules() -> &'static [SyncRule] {
DEFAULT_SYNC_RULES.get_or_init(|| {
vec![
sync_rule!("*.server.lua", ServerScript, ".server.lua"),
sync_rule!("*.server.luau", ServerScript, ".server.luau"),
sync_rule!("*.client.lua", ClientScript, ".client.lua"),
sync_rule!("*.client.luau", ClientScript, ".client.luau"),
sync_rule!("*.plugin.lua", PluginScript, ".plugin.lua"),
sync_rule!("*.plugin.luau", PluginScript, ".plugin.luau"),
sync_rule!("*.legacy.lua", LegacyScript, ".legacy.lua"),
sync_rule!("*.legacy.luau", LegacyScript, ".legacy.luau"),
sync_rule!("*.local.lua", LocalScript, ".local.lua"),
sync_rule!("*.local.luau", LocalScript, ".local.luau"),
sync_rule!("*.{lua,luau}", ModuleScript),
sync_rule!("*.project.json", Project, ".project.json"),
sync_rule!("*.project.jsonc", Project, ".project.jsonc"),
sync_rule!("*.luau", ModuleScript),
sync_rule!("*.project.json5", Project, ".project.json5"),
sync_rule!("*.model.json", JsonModel, ".model.json"),
sync_rule!("*.model.jsonc", JsonModel, ".model.jsonc"),
sync_rule!("*.model.json5", JsonModel, ".model.json5"),
sync_rule!("*.json", Json, ".json", "*.meta.json"),
sync_rule!("*.jsonc", Json, ".jsonc", "*.meta.jsonc"),
sync_rule!("*.json5", Json, ".json5", "*.meta.json5"),
sync_rule!("*.toml", Toml),
sync_rule!("*.csv", Csv),

View file

@ -692,7 +692,7 @@ mod test {
imfs.load_snapshot(
"/foo",
VfsSnapshot::dir([(
"default.project.json",
"default.project.json5",
VfsSnapshot::file(
r#"
{
@ -729,7 +729,7 @@ mod test {
imfs.load_snapshot(
"/foo",
VfsSnapshot::dir([(
"hello.project.json",
"hello.project.json5",
VfsSnapshot::file(
r#"
{
@ -749,7 +749,7 @@ mod test {
let instance_snapshot = snapshot_project(
&InstanceContext::default(),
&vfs,
Path::new("/foo/hello.project.json"),
Path::new("/foo/hello.project.json5"),
"NOT_IN_SNAPSHOT",
)
.expect("snapshot error")
@ -764,7 +764,7 @@ mod test {
let mut imfs = InMemoryFs::new();
imfs.load_snapshot(
"/foo.project.json",
"/foo.project.json5",
VfsSnapshot::file(
r#"
{
@ -788,7 +788,7 @@ mod test {
let instance_snapshot = snapshot_project(
&InstanceContext::default(),
&vfs,
Path::new("/foo.project.json"),
Path::new("/foo.project.json5"),
"NOT_IN_SNAPSHOT",
)
.expect("snapshot error")
@ -803,7 +803,7 @@ mod test {
let mut imfs = InMemoryFs::new();
imfs.load_snapshot(
"/foo.project.json",
"/foo.project.json5",
VfsSnapshot::file(
r#"
{
@ -825,7 +825,7 @@ mod test {
let instance_snapshot = snapshot_project(
&InstanceContext::default(),
&vfs,
Path::new("/foo.project.json"),
Path::new("/foo.project.json5"),
"NOT_IN_SNAPSHOT",
)
.expect("snapshot error")
@ -840,7 +840,7 @@ mod test {
let mut imfs = InMemoryFs::new();
imfs.load_snapshot(
"/foo.project.json",
"/foo.project.json5",
VfsSnapshot::file(
r#"
{
@ -863,7 +863,7 @@ mod test {
let instance_snapshot = snapshot_project(
&InstanceContext::default(),
&vfs,
Path::new("/foo.project.json"),
Path::new("/foo.project.json5"),
"NOT_IN_SNAPSHOT",
)
.expect("snapshot error")
@ -881,7 +881,7 @@ mod test {
"/foo",
VfsSnapshot::dir([
(
"default.project.json",
"default.project.json5",
VfsSnapshot::file(
r#"
{
@ -903,7 +903,7 @@ mod test {
let instance_snapshot = snapshot_project(
&InstanceContext::default(),
&vfs,
Path::new("/foo/default.project.json"),
Path::new("/foo/default.project.json5"),
"NOT_IN_SNAPSHOT",
)
.expect("snapshot error")
@ -921,20 +921,20 @@ mod test {
"/foo",
VfsSnapshot::dir([
(
"default.project.json",
"default.project.json5",
VfsSnapshot::file(
r#"
{
"name": "path-project",
"tree": {
"$path": "other.project.json"
"$path": "other.project.json5"
}
}
"#,
),
),
(
"other.project.json",
"other.project.json5",
VfsSnapshot::file(
r#"
{
@ -955,7 +955,7 @@ mod test {
let instance_snapshot = snapshot_project(
&InstanceContext::default(),
&vfs,
Path::new("/foo/default.project.json"),
Path::new("/foo/default.project.json5"),
"NOT_IN_SNAPSHOT",
)
.expect("snapshot error")
@ -973,20 +973,20 @@ mod test {
"/foo",
VfsSnapshot::dir([
(
"default.project.json",
"default.project.json5",
VfsSnapshot::file(
r#"
{
"name": "path-child-project",
"tree": {
"$path": "other.project.json"
"$path": "other.project.json5"
}
}
"#,
),
),
(
"other.project.json",
"other.project.json5",
VfsSnapshot::file(
r#"
{
@ -1011,7 +1011,7 @@ mod test {
let instance_snapshot = snapshot_project(
&InstanceContext::default(),
&vfs,
Path::new("/foo/default.project.json"),
Path::new("/foo/default.project.json5"),
"NOT_IN_SNAPSHOT",
)
.expect("snapshot error")
@ -1032,13 +1032,13 @@ mod test {
"/foo",
VfsSnapshot::dir([
(
"default.project.json",
"default.project.json5",
VfsSnapshot::file(
r#"
{
"name": "path-property-override",
"tree": {
"$path": "other.project.json",
"$path": "other.project.json5",
"$properties": {
"Value": "Changed"
}
@ -1048,7 +1048,7 @@ mod test {
),
),
(
"other.project.json",
"other.project.json5",
VfsSnapshot::file(
r#"
{
@ -1072,7 +1072,7 @@ mod test {
let instance_snapshot = snapshot_project(
&InstanceContext::default(),
&vfs,
Path::new("/foo/default.project.json"),
Path::new("/foo/default.project.json5"),
"NOT_IN_SNAPSHOT",
)
.expect("snapshot error")
@ -1089,7 +1089,7 @@ mod test {
imfs.load_snapshot(
"/foo",
VfsSnapshot::dir([(
"default.project.json",
"default.project.json5",
VfsSnapshot::file(
r#"
{
@ -1108,7 +1108,7 @@ mod test {
let instance_snapshot = snapshot_project(
&InstanceContext::default(),
&vfs,
Path::new("/foo/default.project.json"),
Path::new("/foo/default.project.json5"),
"no_name_project",
)
.expect("snapshot error")

View file

@ -9,8 +9,6 @@ metadata:
Path: /foo.csv
relevant_paths:
- /foo.csv
- /foo.meta.json
- /foo.meta.jsonc
- /foo.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -16,8 +16,6 @@ metadata:
- /root/init.client.lua
- /root/init.client.luau
- /root/init.csv
- /root/init.meta.json
- /root/init.meta.jsonc
- /root/init.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -16,8 +16,6 @@ metadata:
- /root/init.client.lua
- /root/init.client.luau
- /root/init.csv
- /root/init.meta.json
- /root/init.meta.jsonc
- /root/init.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -9,8 +9,6 @@ metadata:
Path: /foo.csv
relevant_paths:
- /foo.csv
- /foo.meta.json
- /foo.meta.jsonc
- /foo.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -16,8 +16,6 @@ metadata:
- /foo/init.client.lua
- /foo/init.client.luau
- /foo/init.csv
- /foo/init.meta.json
- /foo/init.meta.jsonc
- /foo/init.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -16,8 +16,6 @@ metadata:
- /foo/init.client.lua
- /foo/init.client.luau
- /foo/init.csv
- /foo/init.meta.json
- /foo/init.meta.jsonc
- /foo/init.meta.json5
context:
decode_windows_invalid_chars: true
@ -42,8 +40,6 @@ children:
- /foo/Child/init.client.lua
- /foo/Child/init.client.luau
- /foo/Child/init.csv
- /foo/Child/init.meta.json
- /foo/Child/init.meta.jsonc
- /foo/Child/init.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -9,8 +9,6 @@ metadata:
Path: /foo.json
relevant_paths:
- /foo.json
- /foo.meta.json
- /foo.meta.jsonc
- /foo.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -9,8 +9,6 @@ metadata:
Path: /foo.json
relevant_paths:
- /foo.json
- /foo.meta.json
- /foo.meta.jsonc
- /foo.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -6,11 +6,9 @@ snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: false
instigating_source:
Path: /foo.client.lua
Path: /foo.client.luau
relevant_paths:
- /foo.client.lua
- /foo.meta.json
- /foo.meta.jsonc
- /foo.client.luau
- /foo.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -6,7 +6,7 @@ snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: false
instigating_source:
Path: /root/init.lua
Path: /root/init.luau
relevant_paths:
- /root
- /root/init.lua
@ -16,8 +16,6 @@ metadata:
- /root/init.client.lua
- /root/init.client.luau
- /root/init.csv
- /root/init.meta.json
- /root/init.meta.jsonc
- /root/init.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -6,7 +6,7 @@ snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: false
instigating_source:
Path: /root/init.lua
Path: /root/init.luau
relevant_paths:
- /root
- /root/init.lua
@ -16,8 +16,6 @@ metadata:
- /root/init.client.lua
- /root/init.client.luau
- /root/init.csv
- /root/init.meta.json
- /root/init.meta.jsonc
- /root/init.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -6,11 +6,9 @@ snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: false
instigating_source:
Path: /foo.legacy.lua
Path: /foo.legacy.luau
relevant_paths:
- /foo.legacy.lua
- /foo.meta.json
- /foo.meta.jsonc
- /foo.legacy.luau
- /foo.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -6,11 +6,9 @@ snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: false
instigating_source:
Path: /foo.local.lua
Path: /foo.local.luau
relevant_paths:
- /foo.local.lua
- /foo.meta.json
- /foo.meta.jsonc
- /foo.local.luau
- /foo.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -6,11 +6,9 @@ snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: false
instigating_source:
Path: /foo.lua
Path: /foo.luau
relevant_paths:
- /foo.lua
- /foo.meta.json
- /foo.meta.jsonc
- /foo.luau
- /foo.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -6,11 +6,9 @@ snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: true
instigating_source:
Path: /foo.lua
Path: /foo.luau
relevant_paths:
- /foo.lua
- /foo.meta.json
- /foo.meta.jsonc
- /foo.luau
- /foo.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -6,11 +6,9 @@ snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: false
instigating_source:
Path: /foo.plugin.lua
Path: /foo.plugin.luau
relevant_paths:
- /foo.plugin.lua
- /foo.meta.json
- /foo.meta.jsonc
- /foo.plugin.luau
- /foo.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -6,11 +6,9 @@ snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: false
instigating_source:
Path: /bar.server.lua
Path: /bar.server.luau
relevant_paths:
- /bar.server.lua
- /bar.meta.json
- /bar.meta.jsonc
- /bar.server.luau
- /bar.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -6,11 +6,9 @@ snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: false
instigating_source:
Path: /foo.server.lua
Path: /foo.server.luau
relevant_paths:
- /foo.server.lua
- /foo.meta.json
- /foo.meta.jsonc
- /foo.server.luau
- /foo.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -6,11 +6,9 @@ snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: true
instigating_source:
Path: /foo.server.lua
Path: /foo.server.luau
relevant_paths:
- /foo.server.lua
- /foo.meta.json
- /foo.meta.jsonc
- /foo.server.luau
- /foo.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -0,0 +1,18 @@
---
source: src/snapshot_middleware/meta_file.rs
expression: snapshot
---
snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: false
relevant_paths:
- /foo/bar.meta.json5
context:
decode_windows_invalid_chars: true
specified_id: manually specified
middleware: ~
schema: ~
name: DEFAULT
class_name: DEFAULT
properties: {}
children: []

View file

@ -0,0 +1,18 @@
---
source: src/snapshot_middleware/meta_file.rs
expression: snapshot
---
snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: false
relevant_paths:
- /foo/init.meta.json5
context:
decode_windows_invalid_chars: true
specified_id: manually specified
middleware: ~
schema: ~
name: DEFAULT
class_name: DEFAULT
properties: {}
children: []

View file

@ -6,9 +6,9 @@ snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: true
instigating_source:
Path: /foo/default.project.json
Path: /foo/default.project.json5
relevant_paths:
- /foo/default.project.json
- /foo/default.project.json5
context:
decode_windows_invalid_chars: true
specified_id: ~

View file

@ -6,9 +6,9 @@ snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: true
instigating_source:
Path: /foo/hello.project.json
Path: /foo/hello.project.json5
relevant_paths:
- /foo/hello.project.json
- /foo/hello.project.json5
context:
decode_windows_invalid_chars: true
specified_id: ~

View file

@ -6,10 +6,10 @@ snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: true
instigating_source:
Path: /foo/default.project.json
Path: /foo/default.project.json5
relevant_paths:
- /foo/other.project.json
- /foo/default.project.json
- /foo/other.project.json5
- /foo/default.project.json5
context:
decode_windows_invalid_chars: true
specified_id: ~

View file

@ -6,9 +6,9 @@ snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: true
instigating_source:
Path: /foo.project.json
Path: /foo.project.json5
relevant_paths:
- /foo.project.json
- /foo.project.json5
context:
decode_windows_invalid_chars: true
specified_id: ~
@ -23,7 +23,7 @@ children:
ignore_unknown_instances: true
instigating_source:
ProjectNode:
path: /foo.project.json
path: /foo.project.json5
name: Child
node:
$className: Model

View file

@ -6,10 +6,10 @@ snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: true
instigating_source:
Path: /foo/default.project.json
Path: /foo/default.project.json5
relevant_paths:
- /foo/other.project.json
- /foo/default.project.json
- /foo/other.project.json5
- /foo/default.project.json5
context:
decode_windows_invalid_chars: true
specified_id: ~

View file

@ -6,10 +6,10 @@ snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: true
instigating_source:
Path: /foo/default.project.json
Path: /foo/default.project.json5
relevant_paths:
- /foo/other.project.json
- /foo/default.project.json
- /foo/other.project.json5
- /foo/default.project.json5
context:
decode_windows_invalid_chars: true
specified_id: ~
@ -24,7 +24,7 @@ children:
ignore_unknown_instances: true
instigating_source:
ProjectNode:
path: /foo/other.project.json
path: /foo/other.project.json5
name: SomeChild
node:
$className: Model

View file

@ -6,13 +6,11 @@ snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: false
instigating_source:
Path: /foo/default.project.json
Path: /foo/default.project.json5
relevant_paths:
- /foo/other.txt
- /foo/other.meta.json
- /foo/other.meta.jsonc
- /foo/other.meta.json5
- /foo/default.project.json
- /foo/default.project.json5
context:
decode_windows_invalid_chars: true
specified_id: ~

View file

@ -6,9 +6,9 @@ snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: true
instigating_source:
Path: /foo.project.json
Path: /foo.project.json5
relevant_paths:
- /foo.project.json
- /foo.project.json5
context:
decode_windows_invalid_chars: true
specified_id: ~

View file

@ -6,9 +6,9 @@ snapshot_id: "00000000000000000000000000000000"
metadata:
ignore_unknown_instances: true
instigating_source:
Path: /foo.project.json
Path: /foo.project.json5
relevant_paths:
- /foo.project.json
- /foo.project.json5
context:
decode_windows_invalid_chars: true
specified_id: ~

View file

@ -9,8 +9,6 @@ metadata:
Path: /foo.toml
relevant_paths:
- /foo.toml
- /foo.meta.json
- /foo.meta.jsonc
- /foo.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -9,8 +9,6 @@ metadata:
Path: foo.toml
relevant_paths:
- foo.toml
- foo.meta.json
- foo.meta.jsonc
- foo.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -9,8 +9,6 @@ metadata:
Path: /foo.txt
relevant_paths:
- /foo.txt
- /foo.meta.json
- /foo.meta.jsonc
- /foo.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -9,8 +9,6 @@ metadata:
Path: /foo.txt
relevant_paths:
- /foo.txt
- /foo.meta.json
- /foo.meta.jsonc
- /foo.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -9,8 +9,6 @@ metadata:
Path: /foo.yaml
relevant_paths:
- /foo.yaml
- /foo.meta.json
- /foo.meta.jsonc
- /foo.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -9,8 +9,6 @@ metadata:
Path: foo.yaml
relevant_paths:
- foo.yaml
- foo.meta.json
- foo.meta.jsonc
- foo.meta.json5
context:
decode_windows_invalid_chars: true

View file

@ -130,7 +130,7 @@ mod test {
)
.unwrap();
imfs.load_snapshot(
"foo.meta.json",
"foo.meta.json5",
VfsSnapshot::file(
r#"{
"id": "manually specified"

View file

@ -110,7 +110,7 @@ mod test {
imfs.load_snapshot("/foo.txt", VfsSnapshot::file("Hello there!"))
.unwrap();
imfs.load_snapshot(
"/foo.meta.json",
"/foo.meta.json5",
VfsSnapshot::file(
r#"{
"id": "manually specified"

View file

@ -240,7 +240,7 @@ value: 9007199254740993
)
.unwrap();
imfs.load_snapshot(
"foo.meta.json",
"foo.meta.json5",
VfsSnapshot::file(
r#"{
"id": "manually specified",

View file

@ -32,7 +32,7 @@ use crate::{
web_api::{InstanceUpdate, RefPatchResponse, SerializeResponse},
};
/// Convert a Variant to a JSON-compatible value for .model.json files
/// Convert a Variant to a JSON-compatible value for .model.json5 files
fn variant_to_json(variant: &Variant) -> Option<serde_json::Value> {
use serde_json::{json, Value};
@ -1240,7 +1240,7 @@ impl ApiService {
}
}
/// If this instance is represented by a script, try to find the correct .lua or .luau
/// If this instance is represented by a script, try to find the correct .luau
/// file to open to edit it.
fn pick_script_path(instance: InstanceWithMeta<'_>) -> Option<PathBuf> {
match instance.class_name().as_str() {
@ -1248,16 +1248,15 @@ fn pick_script_path(instance: InstanceWithMeta<'_>) -> Option<PathBuf> {
_ => return None,
}
// Pick the first listed relevant path that has an extension of .lua or .luau that
// Pick the first listed relevant path that has an extension of .luau that
// exists.
instance
.metadata()
.relevant_paths
.iter()
.find(|path| {
// We should only ever open Lua or Luau files to be safe.
// We should only ever open Luau files to be safe.
match path.extension().and_then(|ext| ext.to_str()) {
Some("lua") => {}
Some("luau") => {}
_ => return false,
}
@ -1708,7 +1707,7 @@ mod tests {
let file_name = match class_name {
"ModuleScript" => format!("{}.luau", name),
"LocalScript" => format!("{}.local.luau", name),
_ => format!("{}.model.json", name),
_ => format!("{}.model.json5", name),
};
assert_eq!(
file_name, expected,
@ -1720,7 +1719,7 @@ mod tests {
#[test]
fn test_folder_creates_directory() {
// Folders should not create .model.json files
// Folders should not create .model.json5 files
let class_name = "Folder";
let should_create_file = class_name != "Folder";
assert!(
@ -1791,7 +1790,7 @@ mod tests {
}
}
// Tests for model.json structure
// Tests for model.json5 structure
mod model_json_structure_tests {
use serde_json::json;