diff --git a/Cargo.lock b/Cargo.lock index ad7afd3d..ebc23612 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1533,6 +1533,7 @@ version = "0.1.0" dependencies = [ "insta 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rojo 0.5.0-alpha.13", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/rojo-test/Cargo.toml b/rojo-test/Cargo.toml index cb768b77..43403be0 100644 --- a/rojo-test/Cargo.toml +++ b/rojo-test/Cargo.toml @@ -8,4 +8,7 @@ publish = false [dependencies] insta = "0.10.0" paste = "0.1.5" -tempfile = "3.1.0" \ No newline at end of file +tempfile = "3.1.0" + +# We execute Rojo via std::process::Command, so depend on it so it's built! +rojo = { path = "../server" } \ No newline at end of file diff --git a/rojo-test/build-tests/json_model_in_folder/folder/foo.model.json b/rojo-test/build-tests/json_model_in_folder/folder/simple-model.model.json similarity index 84% rename from rojo-test/build-tests/json_model_in_folder/folder/foo.model.json rename to rojo-test/build-tests/json_model_in_folder/folder/simple-model.model.json index 260f6c7e..0de9921e 100644 --- a/rojo-test/build-tests/json_model_in_folder/folder/foo.model.json +++ b/rojo-test/build-tests/json_model_in_folder/folder/simple-model.model.json @@ -1,5 +1,4 @@ { - "Name": "Top-Level Value", "ClassName": "IntValue", "Properties": { "Value": 5 diff --git a/rojo-test/build-tests/json_model_legacy_name/default.project.json b/rojo-test/build-tests/json_model_legacy_name/default.project.json new file mode 100644 index 00000000..c7c56c0d --- /dev/null +++ b/rojo-test/build-tests/json_model_legacy_name/default.project.json @@ -0,0 +1,6 @@ +{ + "name": "json_model_legacy_name", + "tree": { + "$path": "folder" + } +} \ No newline at end of file diff --git a/rojo-test/build-tests/json_model_legacy_name/folder/Expected Name.model.json b/rojo-test/build-tests/json_model_legacy_name/folder/Expected Name.model.json new file mode 100644 index 00000000..b816d601 --- /dev/null +++ b/rojo-test/build-tests/json_model_legacy_name/folder/Expected Name.model.json @@ -0,0 +1,4 @@ +{ + "Name": "Overridden Name", + "ClassName": "Folder" +} \ No newline at end of file diff --git a/rojo-test/src/build_test.rs b/rojo-test/src/build_test.rs index 6f0b9614..c2f21bdd 100644 --- a/rojo-test/src/build_test.rs +++ b/rojo-test/src/build_test.rs @@ -27,6 +27,7 @@ gen_build_tests! { csv_in_folder, gitkeep, json_model_in_folder, + json_model_legacy_name, module_in_folder, rbxm_in_folder, rbxmx_in_folder, @@ -44,11 +45,16 @@ fn run_build_test(test_name: &str) { let input_path = build_test_path.join(test_name); let output_path = output_dir.path().join(format!("{}.rbxmx", test_name)); - let status = Command::new("cargo") + let mut exe_path = working_dir.join("target/debug/rojo"); + if cfg!(windows) { + exe_path.set_extension("exe"); + } + + let status = Command::new(exe_path) .args(&[ - "run", "--quiet", "--", "build", input_path.to_str().unwrap(), "-o", output_path.to_str().unwrap(), ]) + .env("RUST_LOG", "error") .current_dir(working_dir) .status() .expect("Couldn't start Rojo"); diff --git a/rojo-test/src/snapshots/build_test__json_model_in_folder.snap b/rojo-test/src/snapshots/build_test__json_model_in_folder.snap index 5151ba9a..f6242974 100644 --- a/rojo-test/src/snapshots/build_test__json_model_in_folder.snap +++ b/rojo-test/src/snapshots/build_test__json_model_in_folder.snap @@ -1,5 +1,5 @@ --- -created: "2019-08-15T01:02:40.318937300Z" +created: "2019-08-15T20:40:50.467761900Z" creator: insta@0.10.0 source: rojo-test/src/build_test.rs expression: contents @@ -11,7 +11,7 @@ expression: contents - Top-Level Value + simple-model 5 diff --git a/rojo-test/src/snapshots/build_test__json_model_legacy_name.snap b/rojo-test/src/snapshots/build_test__json_model_legacy_name.snap new file mode 100644 index 00000000..adf985c7 --- /dev/null +++ b/rojo-test/src/snapshots/build_test__json_model_legacy_name.snap @@ -0,0 +1,18 @@ +--- +created: "2019-08-15T20:41:28.743618200Z" +creator: insta@0.10.0 +source: rojo-test/src/build_test.rs +expression: contents +--- + + + + json_model_legacy_name + + + + Expected Name + + + + diff --git a/server/src/rbx_snapshot.rs b/server/src/rbx_snapshot.rs index 72369dce..8ed65ea7 100644 --- a/server/src/rbx_snapshot.rs +++ b/server/src/rbx_snapshot.rs @@ -724,28 +724,63 @@ fn snapshot_csv_file<'source>( fn snapshot_json_model_file<'source>( file: &'source ImfsFile, ) -> SnapshotResult<'source> { + let file_name = file.path + .file_name().expect("Could not extract file stem") + .to_str().expect("Could not convert path to UTF-8"); + + let instance_name = match_trailing(file_name, ".model.json") + .expect("JSON model file did not end in .model.json"); + let contents = str::from_utf8(&file.contents) .map_err(|inner| SnapshotError::Utf8Error { inner, path: file.path.to_owned(), })?; - let json_instance: JsonModelInstance = serde_json::from_str(contents) + let json_instance: JsonModel = serde_json::from_str(contents) .map_err(|inner| SnapshotError::JsonModelDecodeError { inner, path: file.path.to_owned(), })?; - let mut snapshot = json_instance.into_snapshot()?; + if let Some(json_name) = &json_instance.name { + if json_name != instance_name { + log::warn!("Name from JSON model did not match its file name: {}", file.path.display()); + log::warn!("In Rojo < alpha 14, this model is named \"{}\" (from its 'Name' property)", json_name); + log::warn!("In Rojo >= alpha 14, this model is named \"{}\" (from its file name)", instance_name); + log::warn!("'Name' for the top-level instance in a JSON model is now optional and will be ignored."); + } + } + + let mut snapshot = json_instance.core.into_snapshot(instance_name.to_owned())?; + + snapshot.name = Cow::Borrowed(instance_name); snapshot.metadata.source_path = Some(file.path.to_owned()); Ok(Some(snapshot)) } +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +struct JsonModel { + name: Option, + + #[serde(flatten)] + core: JsonModelCore, +} + #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "PascalCase")] struct JsonModelInstance { name: String, + + #[serde(flatten)] + core: JsonModelCore, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +struct JsonModelCore { class_name: String, #[serde(default = "Vec::new", skip_serializing_if = "Vec::is_empty")] @@ -755,12 +790,12 @@ struct JsonModelInstance { properties: HashMap, } -impl JsonModelInstance { - fn into_snapshot(self) -> Result, SnapshotError> { +impl JsonModelCore { + fn into_snapshot(self, name: String) -> Result, SnapshotError> { let mut children = Vec::with_capacity(self.children.len()); for child in self.children { - children.push(child.into_snapshot()?); + children.push(child.core.into_snapshot(child.name)?); } let mut properties = HashMap::with_capacity(self.properties.len()); @@ -771,7 +806,7 @@ impl JsonModelInstance { } Ok(RbxSnapshotInstance { - name: Cow::Owned(self.name), + name: Cow::Owned(name), class_name: Cow::Owned(self.class_name), properties, children,