mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-20 12:45:05 +00:00
Support .jsonc extension for all JSON files (#1159)
This commit is contained in:
@@ -31,6 +31,10 @@ Making a new release? Simply add the new header with the version and date undern
|
||||
|
||||
## Unreleased
|
||||
|
||||
* Added support for `.jsonc` files for all JSON-related files (e.g. `.project.jsonc` and `.meta.jsonc`) to accompany JSONC support ([#1159])
|
||||
|
||||
[#1159]: https://github.com/rojo-rbx/rojo/pull/1159
|
||||
|
||||
## [7.6.1] (November 6th, 2025)
|
||||
|
||||
* Fixed a bug where the last sync timestamp was not updating correctly in the plugin ([#1132])
|
||||
|
||||
@@ -13,7 +13,8 @@ use thiserror::Error;
|
||||
|
||||
use crate::{glob::Glob, json, resolution::UnresolvedValue, snapshot::SyncRule};
|
||||
|
||||
static PROJECT_FILENAME: &str = "default.project.json";
|
||||
/// Represents 'default' project names that act as `init` files
|
||||
pub static DEFAULT_PROJECT_NAMES: [&str; 2] = ["default.project.json", "default.project.jsonc"];
|
||||
|
||||
/// Error type returned by any function that handles projects.
|
||||
#[derive(Debug, Error)]
|
||||
@@ -131,7 +132,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.json"))
|
||||
.map(|name| name.ends_with(".project.json") || name.ends_with(".project.jsonc"))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
@@ -149,18 +150,19 @@ impl Project {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
let child_path = path.join(PROJECT_FILENAME);
|
||||
let child_meta = fs::metadata(&child_path).ok()?;
|
||||
for filename in DEFAULT_PROJECT_NAMES {
|
||||
let child_path = path.join(filename);
|
||||
let child_meta = fs::metadata(&child_path).ok()?;
|
||||
|
||||
if child_meta.is_file() {
|
||||
Some(child_path)
|
||||
} else {
|
||||
// This is a folder with the same name as a Rojo default project
|
||||
// file.
|
||||
//
|
||||
// That's pretty weird, but we can roll with it.
|
||||
None
|
||||
if child_meta.is_file() {
|
||||
return Some(child_path);
|
||||
}
|
||||
}
|
||||
// This is a folder with the same name as a Rojo default project
|
||||
// file.
|
||||
//
|
||||
// That's pretty weird, but we can roll with it.
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,16 +183,20 @@ impl Project {
|
||||
|
||||
// If you're editing this to be generic, make sure you also alter the
|
||||
// snapshot middleware to support generic init paths.
|
||||
if file_name == PROJECT_FILENAME {
|
||||
let folder_name = self.folder_location().file_name().and_then(OsStr::to_str);
|
||||
if let Some(folder_name) = folder_name {
|
||||
self.name = Some(folder_name.to_string());
|
||||
} else {
|
||||
return Err(Error::FolderNameInvalid {
|
||||
path: self.file_location.clone(),
|
||||
});
|
||||
for default_file_name in DEFAULT_PROJECT_NAMES {
|
||||
if file_name == default_file_name {
|
||||
let folder_name = self.folder_location().file_name().and_then(OsStr::to_str);
|
||||
if let Some(folder_name) = folder_name {
|
||||
self.name = Some(folder_name.to_string());
|
||||
return Ok(());
|
||||
} else {
|
||||
return Err(Error::FolderNameInvalid {
|
||||
path: self.file_location.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if let Some(fallback) = fallback {
|
||||
}
|
||||
if let Some(fallback) = fallback {
|
||||
self.name = Some(fallback.to_string());
|
||||
} else {
|
||||
// As of the time of writing (July 10, 2024) there is no way for
|
||||
@@ -257,6 +263,10 @@ impl Project {
|
||||
project_file_location: &Path,
|
||||
fallback_name: Option<&str>,
|
||||
) -> Result<Self, ProjectError> {
|
||||
log::debug!(
|
||||
"Loading project file from {}",
|
||||
project_file_location.display()
|
||||
);
|
||||
let project_path = project_file_location.to_path_buf();
|
||||
let contents = vfs.read(&project_path).map_err(|e| match e.kind() {
|
||||
io::ErrorKind::NotFound => Error::NoProjectFound {
|
||||
@@ -272,6 +282,24 @@ impl Project {
|
||||
)?)
|
||||
}
|
||||
|
||||
pub(crate) fn load_initial_project(vfs: &Vfs, path: &Path) -> Result<Self, ProjectError> {
|
||||
if Self::is_project_file(path) {
|
||||
Self::load_exact(vfs, path, None)
|
||||
} else {
|
||||
// Check for default projects.
|
||||
for default_project_name in DEFAULT_PROJECT_NAMES {
|
||||
let project_path = path.join(default_project_name);
|
||||
if project_path.exists() {
|
||||
return Self::load_exact(vfs, &project_path, None);
|
||||
}
|
||||
}
|
||||
Err(Error::NoProjectFound {
|
||||
path: path.to_path_buf(),
|
||||
}
|
||||
.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if there are any compatibility issues with this project file and
|
||||
/// warns the user if there are any.
|
||||
fn check_compatibility(&self) {
|
||||
@@ -530,7 +558,7 @@ mod test {
|
||||
|
||||
let project = Project::load_from_slice(
|
||||
project_json.as_bytes(),
|
||||
PathBuf::from("/test/default.project.json"),
|
||||
PathBuf::from("/test/default.project.jsonc"),
|
||||
None,
|
||||
)
|
||||
.expect("Failed to parse project with JSONC features");
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
collections::HashSet,
|
||||
io,
|
||||
net::IpAddr,
|
||||
@@ -101,15 +100,7 @@ impl ServeSession {
|
||||
|
||||
log::trace!("Starting new ServeSession at path {}", start_path.display());
|
||||
|
||||
let project_path = if Project::is_project_file(start_path) {
|
||||
Cow::Borrowed(start_path)
|
||||
} else {
|
||||
Cow::Owned(start_path.join("default.project.json"))
|
||||
};
|
||||
|
||||
log::debug!("Loading project file from {}", project_path.display());
|
||||
|
||||
let root_project = Project::load_exact(&vfs, &project_path, None)?;
|
||||
let root_project = Project::load_initial_project(&vfs, start_path)?;
|
||||
|
||||
let mut tree = RojoTree::new(InstanceSnapshot::new());
|
||||
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
use std::{collections::BTreeMap, path::Path};
|
||||
|
||||
use anyhow::Context;
|
||||
use memofs::{IoResultExt, Vfs};
|
||||
use memofs::Vfs;
|
||||
use rbx_dom_weak::ustr;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot};
|
||||
|
||||
use super::{
|
||||
dir::{dir_meta, snapshot_dir_no_meta},
|
||||
meta_file::AdjacentMetadata,
|
||||
use crate::{
|
||||
snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot},
|
||||
snapshot_middleware::meta_file::DirectoryMetadata,
|
||||
};
|
||||
|
||||
use super::{dir::snapshot_dir_no_meta, meta_file::AdjacentMetadata};
|
||||
|
||||
pub fn snapshot_csv(
|
||||
_context: &InstanceContext,
|
||||
vfs: &Vfs,
|
||||
path: &Path,
|
||||
name: &str,
|
||||
) -> anyhow::Result<Option<InstanceSnapshot>> {
|
||||
let meta_path = path.with_file_name(format!("{}.meta.json", name));
|
||||
let contents = vfs.read(path)?;
|
||||
|
||||
let table_contents = convert_localization_csv(&contents).with_context(|| {
|
||||
@@ -35,13 +34,10 @@ pub fn snapshot_csv(
|
||||
.metadata(
|
||||
InstanceMetadata::new()
|
||||
.instigating_source(path)
|
||||
.relevant_paths(vec![path.to_path_buf(), meta_path.clone()]),
|
||||
.relevant_paths(vec![path.to_path_buf()]),
|
||||
);
|
||||
|
||||
if let Some(meta_contents) = vfs.read(&meta_path).with_not_found()? {
|
||||
let mut metadata = AdjacentMetadata::from_slice(&meta_contents, meta_path)?;
|
||||
metadata.apply_all(&mut snapshot)?;
|
||||
}
|
||||
AdjacentMetadata::read_and_apply_all(vfs, path, name, &mut snapshot)?;
|
||||
|
||||
Ok(Some(snapshot))
|
||||
}
|
||||
@@ -75,9 +71,7 @@ pub fn snapshot_csv_init(
|
||||
init_snapshot.children = dir_snapshot.children;
|
||||
init_snapshot.metadata = dir_snapshot.metadata;
|
||||
|
||||
if let Some(mut meta) = dir_meta(vfs, folder_path)? {
|
||||
meta.apply_all(&mut init_snapshot)?;
|
||||
}
|
||||
DirectoryMetadata::read_and_apply_all(vfs, folder_path, &mut init_snapshot)?;
|
||||
|
||||
Ok(Some(init_snapshot))
|
||||
}
|
||||
@@ -223,4 +217,72 @@ Ack,Ack!,,An exclamation of despair,¡Ay!"#,
|
||||
|
||||
insta::assert_yaml_snapshot!(instance_snapshot);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn csv_init() {
|
||||
let mut imfs = InMemoryFs::new();
|
||||
imfs.load_snapshot(
|
||||
"/root",
|
||||
VfsSnapshot::dir([(
|
||||
"init.csv",
|
||||
VfsSnapshot::file(
|
||||
r#"
|
||||
Key,Source,Context,Example,es
|
||||
Ack,Ack!,,An exclamation of despair,¡Ay!"#,
|
||||
),
|
||||
)]),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let vfs = Vfs::new(imfs);
|
||||
|
||||
let instance_snapshot = snapshot_csv_init(
|
||||
&InstanceContext::with_emit_legacy_scripts(Some(true)),
|
||||
&vfs,
|
||||
Path::new("/root/init.csv"),
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
insta::with_settings!({ sort_maps => true }, {
|
||||
insta::assert_yaml_snapshot!(instance_snapshot);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn csv_init_with_meta() {
|
||||
let mut imfs = InMemoryFs::new();
|
||||
imfs.load_snapshot(
|
||||
"/root",
|
||||
VfsSnapshot::dir([
|
||||
(
|
||||
"init.csv",
|
||||
VfsSnapshot::file(
|
||||
r#"
|
||||
Key,Source,Context,Example,es
|
||||
Ack,Ack!,,An exclamation of despair,¡Ay!"#,
|
||||
),
|
||||
),
|
||||
(
|
||||
"init.meta.json",
|
||||
VfsSnapshot::file(r#"{"id": "manually specified"}"#),
|
||||
),
|
||||
]),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let vfs = Vfs::new(imfs);
|
||||
|
||||
let instance_snapshot = snapshot_csv_init(
|
||||
&InstanceContext::with_emit_legacy_scripts(Some(true)),
|
||||
&vfs,
|
||||
Path::new("/root/init.csv"),
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
insta::with_settings!({ sort_maps => true }, {
|
||||
insta::assert_yaml_snapshot!(instance_snapshot);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::path::Path;
|
||||
|
||||
use memofs::{DirEntry, IoResultExt, Vfs};
|
||||
use memofs::{DirEntry, Vfs};
|
||||
|
||||
use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot};
|
||||
|
||||
@@ -16,26 +16,11 @@ pub fn snapshot_dir(
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
if let Some(mut meta) = dir_meta(vfs, path)? {
|
||||
meta.apply_all(&mut snapshot)?;
|
||||
}
|
||||
DirectoryMetadata::read_and_apply_all(vfs, path, &mut snapshot)?;
|
||||
|
||||
Ok(Some(snapshot))
|
||||
}
|
||||
|
||||
/// Retrieves the meta file that should be applied for this directory, if it
|
||||
/// exists.
|
||||
pub fn dir_meta(vfs: &Vfs, path: &Path) -> anyhow::Result<Option<DirectoryMetadata>> {
|
||||
let meta_path = path.join("init.meta.json");
|
||||
|
||||
if let Some(meta_contents) = vfs.read(&meta_path).with_not_found()? {
|
||||
let metadata = DirectoryMetadata::from_slice(&meta_contents, meta_path)?;
|
||||
Ok(Some(metadata))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
/// Snapshot a directory without applying meta files; useful for if the
|
||||
/// directory's ClassName will change before metadata should be applied. For
|
||||
/// example, this can happen if the directory contains an `init.client.lua`
|
||||
@@ -73,11 +58,8 @@ pub fn snapshot_dir_no_meta(
|
||||
.ok_or_else(|| anyhow::anyhow!("File name was not valid UTF-8: {}", path.display()))?
|
||||
.to_string();
|
||||
|
||||
let meta_path = path.join("init.meta.json");
|
||||
|
||||
let relevant_paths = vec![
|
||||
path.to_path_buf(),
|
||||
meta_path,
|
||||
// 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?
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::path::Path;
|
||||
|
||||
use memofs::{IoResultExt, Vfs};
|
||||
use memofs::Vfs;
|
||||
use rbx_dom_weak::ustr;
|
||||
|
||||
use crate::{
|
||||
@@ -25,8 +25,6 @@ pub fn snapshot_json(
|
||||
|
||||
let as_lua = json_to_lua(value).to_string();
|
||||
|
||||
let meta_path = path.with_file_name(format!("{}.meta.json", name));
|
||||
|
||||
let mut snapshot = InstanceSnapshot::new()
|
||||
.name(name)
|
||||
.class_name("ModuleScript")
|
||||
@@ -34,14 +32,11 @@ pub fn snapshot_json(
|
||||
.metadata(
|
||||
InstanceMetadata::new()
|
||||
.instigating_source(path)
|
||||
.relevant_paths(vec![path.to_path_buf(), meta_path.clone()])
|
||||
.relevant_paths(vec![path.to_path_buf()])
|
||||
.context(context),
|
||||
);
|
||||
|
||||
if let Some(meta_contents) = vfs.read(&meta_path).with_not_found()? {
|
||||
let mut metadata = AdjacentMetadata::from_slice(&meta_contents, meta_path)?;
|
||||
metadata.apply_all(&mut snapshot)?;
|
||||
}
|
||||
AdjacentMetadata::read_and_apply_all(vfs, path, name, &mut snapshot)?;
|
||||
|
||||
Ok(Some(snapshot))
|
||||
}
|
||||
@@ -111,4 +106,42 @@ mod test {
|
||||
|
||||
insta::assert_yaml_snapshot!(instance_snapshot);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn with_metadata() {
|
||||
let mut imfs = InMemoryFs::new();
|
||||
imfs.load_snapshot(
|
||||
"/foo.json",
|
||||
VfsSnapshot::file(
|
||||
r#"{
|
||||
"array": [1, 2, 3],
|
||||
"int": 1234,
|
||||
"float": 1234.5452,
|
||||
}"#,
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
imfs.load_snapshot(
|
||||
"/foo.meta.json",
|
||||
VfsSnapshot::file(
|
||||
r#"{
|
||||
"id": "manually specified"
|
||||
}"#,
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let vfs = Vfs::new(imfs.clone());
|
||||
|
||||
let instance_snapshot = snapshot_json(
|
||||
&InstanceContext::default(),
|
||||
&vfs,
|
||||
Path::new("/foo.json"),
|
||||
"foo",
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
insta::assert_yaml_snapshot!(instance_snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
use std::{path::Path, str};
|
||||
|
||||
use memofs::{IoResultExt, Vfs};
|
||||
use memofs::Vfs;
|
||||
use rbx_dom_weak::{types::Enum, ustr, HashMapExt as _, UstrMap};
|
||||
|
||||
use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot};
|
||||
|
||||
use super::{
|
||||
dir::{dir_meta, snapshot_dir_no_meta},
|
||||
meta_file::AdjacentMetadata,
|
||||
};
|
||||
use super::{dir::snapshot_dir_no_meta, meta_file::AdjacentMetadata, meta_file::DirectoryMetadata};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ScriptType {
|
||||
@@ -73,8 +70,6 @@ pub fn snapshot_lua(
|
||||
);
|
||||
}
|
||||
|
||||
let meta_path = path.with_file_name(format!("{}.meta.json", name));
|
||||
|
||||
let mut snapshot = InstanceSnapshot::new()
|
||||
.name(name)
|
||||
.class_name(class_name)
|
||||
@@ -82,14 +77,11 @@ pub fn snapshot_lua(
|
||||
.metadata(
|
||||
InstanceMetadata::new()
|
||||
.instigating_source(path)
|
||||
.relevant_paths(vec![path.to_path_buf(), meta_path.clone()])
|
||||
.relevant_paths(vec![path.to_path_buf()])
|
||||
.context(context),
|
||||
);
|
||||
|
||||
if let Some(meta_contents) = vfs.read(&meta_path).with_not_found()? {
|
||||
let mut metadata = AdjacentMetadata::from_slice(&meta_contents, meta_path)?;
|
||||
metadata.apply_all(&mut snapshot)?;
|
||||
}
|
||||
AdjacentMetadata::read_and_apply_all(vfs, path, name, &mut snapshot)?;
|
||||
|
||||
Ok(Some(snapshot))
|
||||
}
|
||||
@@ -126,9 +118,7 @@ pub fn snapshot_lua_init(
|
||||
init_snapshot.children = dir_snapshot.children;
|
||||
init_snapshot.metadata = dir_snapshot.metadata;
|
||||
|
||||
if let Some(mut meta) = dir_meta(vfs, folder_path)? {
|
||||
meta.apply_all(&mut init_snapshot)?;
|
||||
}
|
||||
DirectoryMetadata::read_and_apply_all(vfs, folder_path, &mut init_snapshot)?;
|
||||
|
||||
Ok(Some(init_snapshot))
|
||||
}
|
||||
@@ -300,7 +290,6 @@ mod test {
|
||||
});
|
||||
}
|
||||
|
||||
#[ignore = "init.lua functionality has moved to the root snapshot function"]
|
||||
#[test]
|
||||
fn init_module_from_vfs() {
|
||||
let mut imfs = InMemoryFs::new();
|
||||
@@ -312,11 +301,41 @@ mod test {
|
||||
|
||||
let vfs = Vfs::new(imfs);
|
||||
|
||||
let instance_snapshot = snapshot_lua(
|
||||
let instance_snapshot = snapshot_lua_init(
|
||||
&InstanceContext::with_emit_legacy_scripts(Some(true)),
|
||||
&vfs,
|
||||
Path::new("/root"),
|
||||
"root",
|
||||
Path::new("/root/init.lua"),
|
||||
ScriptType::Module,
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
insta::with_settings!({ sort_maps => true }, {
|
||||
insta::assert_yaml_snapshot!(instance_snapshot);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn init_module_from_vfs_with_meta() {
|
||||
let mut imfs = InMemoryFs::new();
|
||||
imfs.load_snapshot(
|
||||
"/root",
|
||||
VfsSnapshot::dir([
|
||||
("init.lua", VfsSnapshot::file("Hello!")),
|
||||
(
|
||||
"init.meta.json",
|
||||
VfsSnapshot::file(r#"{"id": "manually specified"}"#),
|
||||
),
|
||||
]),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let vfs = Vfs::new(imfs);
|
||||
|
||||
let instance_snapshot = snapshot_lua_init(
|
||||
&InstanceContext::with_emit_legacy_scripts(Some(true)),
|
||||
&vfs,
|
||||
Path::new("/root/init.lua"),
|
||||
ScriptType::Module,
|
||||
)
|
||||
.unwrap()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ use anyhow::Context;
|
||||
use memofs::{IoResultExt, Vfs};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::glob::Glob;
|
||||
use crate::snapshot::{InstanceContext, InstanceSnapshot, SyncRule};
|
||||
use crate::{glob::Glob, project::DEFAULT_PROJECT_NAMES};
|
||||
|
||||
use self::{
|
||||
csv::{snapshot_csv, snapshot_csv_init},
|
||||
@@ -122,9 +122,11 @@ pub fn snapshot_from_vfs(
|
||||
fn get_init_path<P: AsRef<Path>>(vfs: &Vfs, dir: P) -> anyhow::Result<Option<PathBuf>> {
|
||||
let path = dir.as_ref();
|
||||
|
||||
let project_path = path.join("default.project.json");
|
||||
if vfs.metadata(&project_path).with_not_found()?.is_some() {
|
||||
return Ok(Some(project_path));
|
||||
for default_project_name in DEFAULT_PROJECT_NAMES {
|
||||
let project_path = path.join(default_project_name);
|
||||
if vfs.metadata(&project_path).with_not_found()?.is_some() {
|
||||
return Ok(Some(project_path));
|
||||
}
|
||||
}
|
||||
|
||||
let init_path = path.join("init.luau");
|
||||
@@ -312,8 +314,11 @@ pub fn default_sync_rules() -> &'static [SyncRule] {
|
||||
sync_rule!("*.plugin.luau", PluginScript, ".plugin.luau"),
|
||||
sync_rule!("*.{lua,luau}", ModuleScript),
|
||||
sync_rule!("*.project.json", Project, ".project.json"),
|
||||
sync_rule!("*.project.jsonc", Project, ".project.jsonc"),
|
||||
sync_rule!("*.model.json", JsonModel, ".model.json"),
|
||||
sync_rule!("*.model.jsonc", JsonModel, ".model.jsonc"),
|
||||
sync_rule!("*.json", Json, ".json", "*.meta.json"),
|
||||
sync_rule!("*.jsonc", Json, ".jsonc", "*.meta.jsonc"),
|
||||
sync_rule!("*.toml", Toml),
|
||||
sync_rule!("*.csv", Csv),
|
||||
sync_rule!("*.txt", Text),
|
||||
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
relevant_paths:
|
||||
- /foo.csv
|
||||
- /foo.meta.json
|
||||
- /foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: ~
|
||||
@@ -19,4 +20,3 @@ properties:
|
||||
Contents:
|
||||
String: "[{\"key\":\"Ack\",\"example\":\"An exclamation of despair\",\"source\":\"Ack!\",\"values\":{\"es\":\"¡Ay!\"}}]"
|
||||
children: []
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
source: src/snapshot_middleware/csv.rs
|
||||
expression: instance_snapshot
|
||||
---
|
||||
snapshot_id: "00000000000000000000000000000000"
|
||||
metadata:
|
||||
ignore_unknown_instances: false
|
||||
instigating_source:
|
||||
Path: /root
|
||||
relevant_paths:
|
||||
- /root
|
||||
- /root/init.lua
|
||||
- /root/init.luau
|
||||
- /root/init.server.lua
|
||||
- /root/init.server.luau
|
||||
- /root/init.client.lua
|
||||
- /root/init.client.luau
|
||||
- /root/init.csv
|
||||
- /root/init.meta.json
|
||||
- /root/init.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: ~
|
||||
name: root
|
||||
class_name: LocalizationTable
|
||||
properties:
|
||||
Contents:
|
||||
String: "[{\"key\":\"Ack\",\"example\":\"An exclamation of despair\",\"source\":\"Ack!\",\"values\":{\"es\":\"¡Ay!\"}}]"
|
||||
children: []
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
source: src/snapshot_middleware/csv.rs
|
||||
expression: instance_snapshot
|
||||
---
|
||||
snapshot_id: "00000000000000000000000000000000"
|
||||
metadata:
|
||||
ignore_unknown_instances: false
|
||||
instigating_source:
|
||||
Path: /root
|
||||
relevant_paths:
|
||||
- /root
|
||||
- /root/init.lua
|
||||
- /root/init.luau
|
||||
- /root/init.server.lua
|
||||
- /root/init.server.luau
|
||||
- /root/init.client.lua
|
||||
- /root/init.client.luau
|
||||
- /root/init.csv
|
||||
- /root/init.meta.json
|
||||
- /root/init.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: manually specified
|
||||
name: root
|
||||
class_name: LocalizationTable
|
||||
properties:
|
||||
Contents:
|
||||
String: "[{\"key\":\"Ack\",\"example\":\"An exclamation of despair\",\"source\":\"Ack!\",\"values\":{\"es\":\"¡Ay!\"}}]"
|
||||
children: []
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
relevant_paths:
|
||||
- /foo.csv
|
||||
- /foo.meta.json
|
||||
- /foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: ~
|
||||
@@ -19,4 +20,3 @@ properties:
|
||||
Contents:
|
||||
String: "[{\"key\":\"Ack\",\"example\":\"An exclamation of despair\",\"source\":\"Ack!\",\"values\":{\"es\":\"¡Ay!\"}}]"
|
||||
children: []
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ metadata:
|
||||
Path: /foo
|
||||
relevant_paths:
|
||||
- /foo
|
||||
- /foo/init.meta.json
|
||||
- /foo/init.lua
|
||||
- /foo/init.luau
|
||||
- /foo/init.server.lua
|
||||
@@ -17,6 +16,8 @@ metadata:
|
||||
- /foo/init.client.lua
|
||||
- /foo/init.client.luau
|
||||
- /foo/init.csv
|
||||
- /foo/init.meta.json
|
||||
- /foo/init.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: ~
|
||||
@@ -24,4 +25,3 @@ name: foo
|
||||
class_name: Folder
|
||||
properties: {}
|
||||
children: []
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ metadata:
|
||||
Path: /foo
|
||||
relevant_paths:
|
||||
- /foo
|
||||
- /foo/init.meta.json
|
||||
- /foo/init.lua
|
||||
- /foo/init.luau
|
||||
- /foo/init.server.lua
|
||||
@@ -17,6 +16,8 @@ metadata:
|
||||
- /foo/init.client.lua
|
||||
- /foo/init.client.luau
|
||||
- /foo/init.csv
|
||||
- /foo/init.meta.json
|
||||
- /foo/init.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: ~
|
||||
@@ -31,7 +32,6 @@ children:
|
||||
Path: /foo/Child
|
||||
relevant_paths:
|
||||
- /foo/Child
|
||||
- /foo/Child/init.meta.json
|
||||
- /foo/Child/init.lua
|
||||
- /foo/Child/init.luau
|
||||
- /foo/Child/init.server.lua
|
||||
@@ -39,6 +39,8 @@ 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
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: ~
|
||||
@@ -46,4 +48,3 @@ children:
|
||||
class_name: Folder
|
||||
properties: {}
|
||||
children: []
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
relevant_paths:
|
||||
- /foo.json
|
||||
- /foo.meta.json
|
||||
- /foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: ~
|
||||
@@ -19,4 +20,3 @@ properties:
|
||||
Source:
|
||||
String: "return {\n\t[\"1invalidident\"] = \"nice\",\n\tarray = {1, 2, 3},\n\t[\"false\"] = false,\n\tfloat = 1234.5452,\n\tint = 1234,\n\tnull = nil,\n\tobject = {\n\t\thello = \"world\",\n\t},\n\t[\"true\"] = true,\n}"
|
||||
children: []
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
source: src/snapshot_middleware/json.rs
|
||||
expression: instance_snapshot
|
||||
---
|
||||
snapshot_id: "00000000000000000000000000000000"
|
||||
metadata:
|
||||
ignore_unknown_instances: false
|
||||
instigating_source:
|
||||
Path: /foo.json
|
||||
relevant_paths:
|
||||
- /foo.json
|
||||
- /foo.meta.json
|
||||
- /foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: manually specified
|
||||
name: foo
|
||||
class_name: ModuleScript
|
||||
properties:
|
||||
Source:
|
||||
String: "return {\n\tarray = {1, 2, 3},\n\tfloat = 1234.5452,\n\tint = 1234,\n}"
|
||||
children: []
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
relevant_paths:
|
||||
- /foo.client.lua
|
||||
- /foo.meta.json
|
||||
- /foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: ~
|
||||
@@ -19,4 +20,3 @@ properties:
|
||||
Source:
|
||||
String: Hello there!
|
||||
children: []
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
relevant_paths:
|
||||
- /foo.lua
|
||||
- /foo.meta.json
|
||||
- /foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: ~
|
||||
@@ -19,4 +20,3 @@ properties:
|
||||
Source:
|
||||
String: Hello there!
|
||||
children: []
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
relevant_paths:
|
||||
- /foo.lua
|
||||
- /foo.meta.json
|
||||
- /foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: ~
|
||||
@@ -19,4 +20,3 @@ properties:
|
||||
Source:
|
||||
String: Hello there!
|
||||
children: []
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
relevant_paths:
|
||||
- /bar.server.lua
|
||||
- /bar.meta.json
|
||||
- /bar.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: ~
|
||||
@@ -23,4 +24,3 @@ properties:
|
||||
Source:
|
||||
String: Hello there!
|
||||
children: []
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
relevant_paths:
|
||||
- /foo.server.lua
|
||||
- /foo.meta.json
|
||||
- /foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: ~
|
||||
@@ -21,4 +22,3 @@ properties:
|
||||
Source:
|
||||
String: Hello there!
|
||||
children: []
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
relevant_paths:
|
||||
- /foo.server.lua
|
||||
- /foo.meta.json
|
||||
- /foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: ~
|
||||
@@ -21,4 +22,3 @@ properties:
|
||||
Source:
|
||||
String: Hello there!
|
||||
children: []
|
||||
|
||||
|
||||
@@ -2,23 +2,28 @@
|
||||
source: src/snapshot_middleware/lua.rs
|
||||
expression: instance_snapshot
|
||||
---
|
||||
snapshot_id: ~
|
||||
snapshot_id: "00000000000000000000000000000000"
|
||||
metadata:
|
||||
ignore_unknown_instances: false
|
||||
instigating_source:
|
||||
Path: /root
|
||||
relevant_paths:
|
||||
- /root
|
||||
- /root/init.meta.json
|
||||
- /root/init.lua
|
||||
- /root/init.luau
|
||||
- /root/init.server.lua
|
||||
- /root/init.server.luau
|
||||
- /root/init.client.lua
|
||||
- /root/init.client.luau
|
||||
- /root/init.csv
|
||||
- /root/init.meta.json
|
||||
- /root/init.meta.jsonc
|
||||
context:
|
||||
script_type: Class
|
||||
emit_legacy_scripts: true
|
||||
specified_id: ~
|
||||
name: root
|
||||
class_name: ModuleScript
|
||||
properties:
|
||||
Source:
|
||||
Type: String
|
||||
Value: Hello!
|
||||
String: Hello!
|
||||
children: []
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
source: src/snapshot_middleware/lua.rs
|
||||
expression: instance_snapshot
|
||||
---
|
||||
snapshot_id: "00000000000000000000000000000000"
|
||||
metadata:
|
||||
ignore_unknown_instances: false
|
||||
instigating_source:
|
||||
Path: /root
|
||||
relevant_paths:
|
||||
- /root
|
||||
- /root/init.lua
|
||||
- /root/init.luau
|
||||
- /root/init.server.lua
|
||||
- /root/init.server.luau
|
||||
- /root/init.client.lua
|
||||
- /root/init.client.luau
|
||||
- /root/init.csv
|
||||
- /root/init.meta.json
|
||||
- /root/init.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: manually specified
|
||||
name: root
|
||||
class_name: ModuleScript
|
||||
properties:
|
||||
Source:
|
||||
String: Hello!
|
||||
children: []
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
relevant_paths:
|
||||
- /foo.plugin.lua
|
||||
- /foo.meta.json
|
||||
- /foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: false
|
||||
specified_id: ~
|
||||
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
relevant_paths:
|
||||
- /foo.client.lua
|
||||
- /foo.meta.json
|
||||
- /foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: false
|
||||
specified_id: ~
|
||||
@@ -21,4 +22,3 @@ properties:
|
||||
Source:
|
||||
String: Hello there!
|
||||
children: []
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
relevant_paths:
|
||||
- /foo.lua
|
||||
- /foo.meta.json
|
||||
- /foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: false
|
||||
specified_id: ~
|
||||
@@ -19,4 +20,3 @@ properties:
|
||||
Source:
|
||||
String: Hello there!
|
||||
children: []
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
relevant_paths:
|
||||
- /foo.lua
|
||||
- /foo.meta.json
|
||||
- /foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: false
|
||||
specified_id: ~
|
||||
@@ -19,4 +20,3 @@ properties:
|
||||
Source:
|
||||
String: Hello there!
|
||||
children: []
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
relevant_paths:
|
||||
- /bar.server.lua
|
||||
- /bar.meta.json
|
||||
- /bar.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: false
|
||||
specified_id: ~
|
||||
@@ -23,4 +24,3 @@ properties:
|
||||
Source:
|
||||
String: Hello there!
|
||||
children: []
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
relevant_paths:
|
||||
- /foo.server.lua
|
||||
- /foo.meta.json
|
||||
- /foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: false
|
||||
specified_id: ~
|
||||
@@ -21,4 +22,3 @@ properties:
|
||||
Source:
|
||||
String: Hello there!
|
||||
children: []
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
relevant_paths:
|
||||
- /foo.server.lua
|
||||
- /foo.meta.json
|
||||
- /foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: false
|
||||
specified_id: ~
|
||||
@@ -21,4 +22,3 @@ properties:
|
||||
Source:
|
||||
String: Hello there!
|
||||
children: []
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
source: src/snapshot_middleware/meta_file.rs
|
||||
expression: snapshot
|
||||
---
|
||||
snapshot_id: "00000000000000000000000000000000"
|
||||
metadata:
|
||||
ignore_unknown_instances: false
|
||||
relevant_paths:
|
||||
- /foo/bar.meta.json
|
||||
- /foo/bar.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: manually specified
|
||||
name: DEFAULT
|
||||
class_name: DEFAULT
|
||||
properties: {}
|
||||
children: []
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
source: src/snapshot_middleware/meta_file.rs
|
||||
expression: snapshot
|
||||
---
|
||||
snapshot_id: "00000000000000000000000000000000"
|
||||
metadata:
|
||||
ignore_unknown_instances: false
|
||||
relevant_paths:
|
||||
- /foo/bar.meta.json
|
||||
- /foo/bar.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: manually specified
|
||||
name: DEFAULT
|
||||
class_name: DEFAULT
|
||||
properties: {}
|
||||
children: []
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
source: src/snapshot_middleware/meta_file.rs
|
||||
expression: snapshot
|
||||
---
|
||||
snapshot_id: "00000000000000000000000000000000"
|
||||
metadata:
|
||||
ignore_unknown_instances: false
|
||||
relevant_paths:
|
||||
- /foo/init.meta.json
|
||||
- /foo/init.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: manually specified
|
||||
name: DEFAULT
|
||||
class_name: DEFAULT
|
||||
properties: {}
|
||||
children: []
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
source: src/snapshot_middleware/meta_file.rs
|
||||
expression: snapshot
|
||||
---
|
||||
snapshot_id: "00000000000000000000000000000000"
|
||||
metadata:
|
||||
ignore_unknown_instances: false
|
||||
relevant_paths:
|
||||
- /foo/init.meta.json
|
||||
- /foo/init.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: manually specified
|
||||
name: DEFAULT
|
||||
class_name: DEFAULT
|
||||
properties: {}
|
||||
children: []
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
relevant_paths:
|
||||
- /foo/other.txt
|
||||
- /foo/other.meta.json
|
||||
- /foo/other.meta.jsonc
|
||||
- /foo/default.project.json
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
@@ -20,4 +21,3 @@ properties:
|
||||
Value:
|
||||
String: "Hello, world!"
|
||||
children: []
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
relevant_paths:
|
||||
- /foo.toml
|
||||
- /foo.meta.json
|
||||
- /foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: ~
|
||||
@@ -19,4 +20,3 @@ properties:
|
||||
Source:
|
||||
String: "return {\n\t[\"1invalidident\"] = \"nice\",\n\tarray = {1, 2, 3},\n\tdates = {\n\t\tlocaldate = \"1979-05-27\",\n\t\tlocaldatetime = \"1979-05-27T07:32:00\",\n\t\tlocaltime = \"00:32:00.999999\",\n\t\toffset1 = \"1979-05-27T00:32:00.999999-07:00\",\n\t\toffset2 = \"1979-05-27T07:32:00Z\",\n\t},\n\t[\"false\"] = false,\n\tfloat = 1234.5452,\n\tint = 1234,\n\tobject = {\n\t\thello = \"world\",\n\t},\n\t[\"true\"] = true,\n}"
|
||||
children: []
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
source: src/snapshot_middleware/toml.rs
|
||||
expression: instance_snapshot
|
||||
---
|
||||
snapshot_id: "00000000000000000000000000000000"
|
||||
metadata:
|
||||
ignore_unknown_instances: false
|
||||
instigating_source:
|
||||
Path: foo.toml
|
||||
relevant_paths:
|
||||
- foo.toml
|
||||
- foo.meta.json
|
||||
- foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: manually specified
|
||||
name: foo
|
||||
class_name: ModuleScript
|
||||
properties:
|
||||
Source:
|
||||
String: "return {\n\tarray = {1, 2, 3},\n\tbool = false,\n\tint = 123,\n}"
|
||||
children: []
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
relevant_paths:
|
||||
- /foo.txt
|
||||
- /foo.meta.json
|
||||
- /foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: ~
|
||||
@@ -19,4 +20,3 @@ properties:
|
||||
Value:
|
||||
String: Hello there!
|
||||
children: []
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
source: src/snapshot_middleware/txt.rs
|
||||
expression: instance_snapshot
|
||||
---
|
||||
snapshot_id: "00000000000000000000000000000000"
|
||||
metadata:
|
||||
ignore_unknown_instances: false
|
||||
instigating_source:
|
||||
Path: /foo.txt
|
||||
relevant_paths:
|
||||
- /foo.txt
|
||||
- /foo.meta.json
|
||||
- /foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: manually specified
|
||||
name: foo
|
||||
class_name: StringValue
|
||||
properties:
|
||||
Value:
|
||||
String: Hello there!
|
||||
children: []
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
relevant_paths:
|
||||
- /foo.yaml
|
||||
- /foo.meta.json
|
||||
- /foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: ~
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
source: src/snapshot_middleware/yaml.rs
|
||||
expression: instance_snapshot
|
||||
---
|
||||
snapshot_id: "00000000000000000000000000000000"
|
||||
metadata:
|
||||
ignore_unknown_instances: false
|
||||
instigating_source:
|
||||
Path: foo.yaml
|
||||
relevant_paths:
|
||||
- foo.yaml
|
||||
- foo.meta.json
|
||||
- foo.meta.jsonc
|
||||
context:
|
||||
emit_legacy_scripts: true
|
||||
specified_id: manually specified
|
||||
name: foo
|
||||
class_name: ModuleScript
|
||||
properties:
|
||||
Source:
|
||||
String: "return {\n\tvalue = 1234,\n}"
|
||||
children: []
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Context;
|
||||
use memofs::{IoResultExt, Vfs};
|
||||
use memofs::Vfs;
|
||||
use rbx_dom_weak::ustr;
|
||||
|
||||
use crate::{
|
||||
@@ -24,8 +24,6 @@ pub fn snapshot_toml(
|
||||
|
||||
let as_lua = toml_to_lua(value).to_string();
|
||||
|
||||
let meta_path = path.with_file_name(format!("{}.meta.json", name));
|
||||
|
||||
let mut snapshot = InstanceSnapshot::new()
|
||||
.name(name)
|
||||
.class_name("ModuleScript")
|
||||
@@ -33,14 +31,11 @@ pub fn snapshot_toml(
|
||||
.metadata(
|
||||
InstanceMetadata::new()
|
||||
.instigating_source(path)
|
||||
.relevant_paths(vec![path.to_path_buf(), meta_path.clone()])
|
||||
.relevant_paths(vec![path.to_path_buf()])
|
||||
.context(context),
|
||||
);
|
||||
|
||||
if let Some(meta_contents) = vfs.read(&meta_path).with_not_found()? {
|
||||
let mut metadata = AdjacentMetadata::from_slice(&meta_contents, meta_path)?;
|
||||
metadata.apply_all(&mut snapshot)?;
|
||||
}
|
||||
AdjacentMetadata::read_and_apply_all(vfs, path, name, &mut snapshot)?;
|
||||
|
||||
Ok(Some(snapshot))
|
||||
}
|
||||
@@ -117,4 +112,42 @@ mod test {
|
||||
|
||||
insta::assert_yaml_snapshot!(instance_snapshot);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn with_metadata() {
|
||||
let mut imfs = InMemoryFs::new();
|
||||
imfs.load_snapshot(
|
||||
"foo.toml",
|
||||
VfsSnapshot::file(
|
||||
r#"
|
||||
array = [1, 2, 3]
|
||||
int = 123
|
||||
bool = false
|
||||
"#,
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
imfs.load_snapshot(
|
||||
"foo.meta.json",
|
||||
VfsSnapshot::file(
|
||||
r#"{
|
||||
"id": "manually specified"
|
||||
}"#,
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let vfs = Vfs::new(imfs.clone());
|
||||
|
||||
let instance_snapshot = snapshot_toml(
|
||||
&InstanceContext::default(),
|
||||
&vfs,
|
||||
Path::new("foo.toml"),
|
||||
"foo",
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
insta::assert_yaml_snapshot!(instance_snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::{path::Path, str};
|
||||
|
||||
use memofs::{IoResultExt, Vfs};
|
||||
use memofs::Vfs;
|
||||
use rbx_dom_weak::ustr;
|
||||
|
||||
use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot};
|
||||
@@ -16,8 +16,6 @@ pub fn snapshot_txt(
|
||||
let contents = vfs.read_to_string(path)?;
|
||||
let contents_str = contents.as_str();
|
||||
|
||||
let meta_path = path.with_file_name(format!("{}.meta.json", name));
|
||||
|
||||
let mut snapshot = InstanceSnapshot::new()
|
||||
.name(name)
|
||||
.class_name("StringValue")
|
||||
@@ -25,14 +23,11 @@ pub fn snapshot_txt(
|
||||
.metadata(
|
||||
InstanceMetadata::new()
|
||||
.instigating_source(path)
|
||||
.relevant_paths(vec![path.to_path_buf(), meta_path.clone()])
|
||||
.relevant_paths(vec![path.to_path_buf()])
|
||||
.context(context),
|
||||
);
|
||||
|
||||
if let Some(meta_contents) = vfs.read(&meta_path).with_not_found()? {
|
||||
let mut metadata = AdjacentMetadata::from_slice(&meta_contents, meta_path)?;
|
||||
metadata.apply_all(&mut snapshot)?;
|
||||
}
|
||||
AdjacentMetadata::read_and_apply_all(vfs, path, name, &mut snapshot)?;
|
||||
|
||||
Ok(Some(snapshot))
|
||||
}
|
||||
@@ -62,4 +57,32 @@ mod test {
|
||||
|
||||
insta::assert_yaml_snapshot!(instance_snapshot);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn with_metadata() {
|
||||
let mut imfs = InMemoryFs::new();
|
||||
imfs.load_snapshot("/foo.txt", VfsSnapshot::file("Hello there!"))
|
||||
.unwrap();
|
||||
imfs.load_snapshot(
|
||||
"/foo.meta.json",
|
||||
VfsSnapshot::file(
|
||||
r#"{
|
||||
"id": "manually specified"
|
||||
}"#,
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
let vfs = Vfs::new(imfs.clone());
|
||||
|
||||
let instance_snapshot = snapshot_txt(
|
||||
&InstanceContext::default(),
|
||||
&vfs,
|
||||
Path::new("/foo.txt"),
|
||||
"foo",
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
insta::assert_yaml_snapshot!(instance_snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Context as _;
|
||||
use memofs::{IoResultExt, Vfs};
|
||||
use memofs::Vfs;
|
||||
use rbx_dom_weak::ustr;
|
||||
use yaml_rust2::{Yaml, YamlLoader};
|
||||
|
||||
@@ -30,8 +30,6 @@ pub fn snapshot_yaml(
|
||||
|
||||
let as_lua = Statement::Return(yaml_to_luau(value)?);
|
||||
|
||||
let meta_path = path.with_file_name(format!("{}.meta.json", name));
|
||||
|
||||
let mut snapshot = InstanceSnapshot::new()
|
||||
.name(name)
|
||||
.class_name("ModuleScript")
|
||||
@@ -39,14 +37,11 @@ pub fn snapshot_yaml(
|
||||
.metadata(
|
||||
InstanceMetadata::new()
|
||||
.instigating_source(path)
|
||||
.relevant_paths(vec![path.to_path_buf(), meta_path.clone()])
|
||||
.relevant_paths(vec![path.to_path_buf()])
|
||||
.context(context),
|
||||
);
|
||||
|
||||
if let Some(meta_contents) = vfs.read(&meta_path).with_not_found()? {
|
||||
let mut metadata = AdjacentMetadata::from_slice(&meta_contents, meta_path)?;
|
||||
metadata.apply_all(&mut snapshot)?;
|
||||
}
|
||||
AdjacentMetadata::read_and_apply_all(vfs, path, name, &mut snapshot)?;
|
||||
|
||||
Ok(Some(snapshot))
|
||||
}
|
||||
@@ -231,4 +226,40 @@ value: 9007199254740993
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn with_metadata() {
|
||||
let mut imfs = InMemoryFs::new();
|
||||
imfs.load_snapshot(
|
||||
"foo.yaml",
|
||||
VfsSnapshot::file(
|
||||
r#"
|
||||
value: 1234
|
||||
"#,
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
imfs.load_snapshot(
|
||||
"foo.meta.json",
|
||||
VfsSnapshot::file(
|
||||
r#"{
|
||||
"id": "manually specified",
|
||||
}"#,
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let vfs = Vfs::new(imfs.clone());
|
||||
|
||||
let instance_snapshot = snapshot_yaml(
|
||||
&InstanceContext::default(),
|
||||
&vfs,
|
||||
Path::new("foo.yaml"),
|
||||
"foo",
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
insta::assert_yaml_snapshot!(instance_snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user