Support .jsonc extension for all JSON files (#1159)

This commit is contained in:
Micah
2025-11-18 18:47:43 -08:00
committed by GitHub
parent 03410ced6d
commit ea70d89291
46 changed files with 759 additions and 153 deletions

View File

@@ -1,6 +1,10 @@
use std::{collections::HashMap, path::PathBuf};
use std::{
collections::HashMap,
path::{Path, PathBuf},
};
use anyhow::{format_err, Context};
use memofs::{IoResultExt as _, Vfs};
use rbx_dom_weak::{types::Attributes, Ustr, UstrMap};
use serde::{Deserialize, Serialize};
@@ -33,7 +37,38 @@ pub struct AdjacentMetadata {
}
impl AdjacentMetadata {
pub fn from_slice(slice: &[u8], path: PathBuf) -> anyhow::Result<Self> {
/// Attempts to read a meta file for the provided path and name, and if
/// one exists applies it.
///
/// Also inserts the potential metadata paths into the snapshot's relevant
/// paths for convenience purposes.
pub fn read_and_apply_all(
vfs: &Vfs,
path: &Path,
name: &str,
snapshot: &mut InstanceSnapshot,
) -> anyhow::Result<()> {
let meta_path_json = path.with_file_name(format!("{name}.meta.json"));
let meta_path_jsonc = path.with_file_name(format!("{name}.meta.jsonc"));
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_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_json);
snapshot.metadata.relevant_paths.push(meta_path_jsonc);
Ok(())
}
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: {}",
@@ -130,7 +165,37 @@ pub struct DirectoryMetadata {
}
impl DirectoryMetadata {
pub fn from_slice(slice: &[u8], path: PathBuf) -> anyhow::Result<Self> {
/// Attempts to read an `init.meta`` file for the provided path, and if
/// one exists applies it.
///
/// Also inserts the potential metadata paths into the snapshot's relevant
/// paths for convenience purposes.
pub fn read_and_apply_all(
vfs: &Vfs,
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");
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)?;
}
// 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);
Ok(())
}
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: {}",
@@ -211,3 +276,82 @@ impl DirectoryMetadata {
Ok(())
}
}
#[cfg(test)]
mod test {
use memofs::{InMemoryFs, VfsSnapshot};
use super::*;
#[test]
fn adjacent_read_json() {
let mut imfs = InMemoryFs::new();
imfs.load_snapshot(
"/foo/bar.meta.json",
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 adjacent_read_jsonc() {
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",
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);
}
}