diff --git a/rojo-test/build-test-snapshots/end_to_end__tests__build__init_csv_with_children.snap b/rojo-test/build-test-snapshots/end_to_end__tests__build__init_csv_with_children.snap new file mode 100644 index 000000000..c089ebb25 --- /dev/null +++ b/rojo-test/build-test-snapshots/end_to_end__tests__build__init_csv_with_children.snap @@ -0,0 +1,19 @@ +--- +source: tests/tests/build.rs +assertion_line: 100 +expression: contents +--- + + + + init_csv_with_children + [{"key":"init.csv","values":{}}] + + + + other + [{"key":"other.csv","values":{}}] + + + + diff --git a/rojo-test/build-tests/init_csv_with_children/default.project.json b/rojo-test/build-tests/init_csv_with_children/default.project.json new file mode 100644 index 000000000..9b77db501 --- /dev/null +++ b/rojo-test/build-tests/init_csv_with_children/default.project.json @@ -0,0 +1,6 @@ +{ + "name": "init_csv_with_children", + "tree": { + "$path": "src" + } +} \ No newline at end of file diff --git a/rojo-test/build-tests/init_csv_with_children/src/init.csv b/rojo-test/build-tests/init_csv_with_children/src/init.csv new file mode 100644 index 000000000..a6bc3e7c0 --- /dev/null +++ b/rojo-test/build-tests/init_csv_with_children/src/init.csv @@ -0,0 +1,2 @@ +Key +init.csv \ No newline at end of file diff --git a/rojo-test/build-tests/init_csv_with_children/src/other.csv b/rojo-test/build-tests/init_csv_with_children/src/other.csv new file mode 100644 index 000000000..0fc62b493 --- /dev/null +++ b/rojo-test/build-tests/init_csv_with_children/src/other.csv @@ -0,0 +1,2 @@ +Key +other.csv \ No newline at end of file diff --git a/src/snapshot_middleware/csv.rs b/src/snapshot_middleware/csv.rs index a8f271808..708f1bb8c 100644 --- a/src/snapshot_middleware/csv.rs +++ b/src/snapshot_middleware/csv.rs @@ -7,7 +7,11 @@ use serde::Serialize; use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot}; -use super::{meta_file::AdjacentMetadata, util::PathExt}; +use super::{ + dir::{dir_meta, snapshot_dir_no_meta}, + meta_file::AdjacentMetadata, + util::PathExt, +}; pub fn snapshot_csv( _context: &InstanceContext, @@ -46,6 +50,43 @@ pub fn snapshot_csv( Ok(Some(snapshot)) } +/// Attempts to snapshot an 'init' csv contained inside of a folder with +/// the given name. +/// +/// csv named `init.csv` +/// their parents, which acts similarly to `__init__.py` from the Python world. +pub fn snapshot_csv_init( + context: &InstanceContext, + vfs: &Vfs, + init_path: &Path, +) -> anyhow::Result> { + let folder_path = init_path.parent().unwrap(); + let dir_snapshot = snapshot_dir_no_meta(context, vfs, folder_path)?.unwrap(); + + if dir_snapshot.class_name != "Folder" { + anyhow::bail!( + "init.csv can only be used if the instance produced by \ + the containing directory would be a Folder.\n\ + \n\ + The directory {} turned into an instance of class {}.", + folder_path.display(), + dir_snapshot.class_name + ); + } + + let mut init_snapshot = snapshot_csv(context, vfs, init_path)?.unwrap(); + + init_snapshot.name = dir_snapshot.name; + 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)?; + } + + Ok(Some(init_snapshot)) +} + /// Struct that holds any valid row from a Roblox CSV translation table. /// /// We manually deserialize into this table from CSV, but let serde_json handle diff --git a/src/snapshot_middleware/mod.rs b/src/snapshot_middleware/mod.rs index 8d27d5bc5..3d5de76bd 100644 --- a/src/snapshot_middleware/mod.rs +++ b/src/snapshot_middleware/mod.rs @@ -24,7 +24,7 @@ use memofs::{IoResultExt, Vfs}; use crate::snapshot::{InstanceContext, InstanceSnapshot}; use self::{ - csv::snapshot_csv, + csv::{snapshot_csv, snapshot_csv_init}, dir::snapshot_dir, json::snapshot_json, json_model::snapshot_json_model, @@ -87,12 +87,19 @@ pub fn snapshot_from_vfs( return snapshot_lua_init(context, vfs, &init_path); } + let init_path = path.join("init.csv"); + if vfs.metadata(&init_path).with_not_found()?.is_some() { + return snapshot_csv_init(context, vfs, &init_path); + } + snapshot_dir(context, vfs, path) } else { let script_name = path .file_name_trim_end(".lua") .or_else(|_| path.file_name_trim_end(".luau")); + let csv_name = path.file_name_trim_end(".csv"); + if let Ok(name) = script_name { match name { // init scripts are handled elsewhere and should not turn into @@ -110,8 +117,14 @@ pub fn snapshot_from_vfs( return Ok(None); } else if path.file_name_ends_with(".json") { return snapshot_json(context, vfs, path); - } else if path.file_name_ends_with(".csv") { - return snapshot_csv(context, vfs, path); + } else if let Ok(name) = csv_name { + match name { + // init csv are handled elsewhere and should not turn into + // their own children. + "init" => return Ok(None), + + _ => return snapshot_csv(context, vfs, path), + } } else if path.file_name_ends_with(".txt") { return snapshot_txt(context, vfs, path); } else if path.file_name_ends_with(".rbxmx") { diff --git a/tests/tests/build.rs b/tests/tests/build.rs index 1776fe7d2..4907449d2 100644 --- a/tests/tests/build.rs +++ b/tests/tests/build.rs @@ -21,6 +21,7 @@ macro_rules! gen_build_tests { } gen_build_tests! { + init_csv_with_children, attributes, client_in_folder, client_init,