mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-21 12:01:38 +00:00
Merge branch 'master' of https://github.com/boatbomber/rojo into headless-api
This commit is contained in:
commit
478cfba11f
6 changed files with 101 additions and 20 deletions
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
|
|
@ -1 +0,0 @@
|
|||
patreon: lpghatguy
|
||||
|
|
@ -18,6 +18,8 @@
|
|||
* Better settings controls ([#725])
|
||||
* Rework patch visualizer with many fixes and improvements ([#726])
|
||||
* Added support for syncing in `.toml` files ([#633])
|
||||
* Add `plugin` flag to the `build` command that outputs to the local plugins folder ([#735])
|
||||
* Added better support for `Font` properties ([#731])
|
||||
|
||||
[#631]: https://github.com/rojo-rbx/rojo/pull/631
|
||||
[#668]: https://github.com/rojo-rbx/rojo/pull/668
|
||||
|
|
@ -36,6 +38,8 @@
|
|||
[#725]: https://github.com/rojo-rbx/rojo/pull/725
|
||||
[#726]: https://github.com/rojo-rbx/rojo/pull/726
|
||||
[#633]: https://github.com/rojo-rbx/rojo/pull/633
|
||||
[#735]: https://github.com/rojo-rbx/rojo/pull/735
|
||||
[#731]: https://github.com/rojo-rbx/rojo/pull/731
|
||||
|
||||
## [7.3.0] - April 22, 2023
|
||||
* Added `$attributes` to project format. ([#574])
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
<a href="https://github.com/rojo-rbx/rojo/actions"><img src="https://github.com/rojo-rbx/rojo/workflows/CI/badge.svg" alt="Actions status" /></a>
|
||||
<a href="https://crates.io/crates/rojo"><img src="https://img.shields.io/crates/v/rojo.svg?label=latest%20release" alt="Latest server version" /></a>
|
||||
<a href="https://rojo.space/docs"><img src="https://img.shields.io/badge/docs-website-brightgreen.svg" alt="Rojo Documentation" /></a>
|
||||
<a href="https://www.patreon.com/lpghatguy"><img src="https://img.shields.io/badge/sponsor-patreon-red" alt="Patreon" /></a>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
|
|
|||
|
|
@ -31,11 +31,12 @@ fn bench_build_place(c: &mut Criterion, name: &str, path: &str) {
|
|||
fn place_setup<P: AsRef<Path>>(input_path: P) -> (TempDir, BuildCommand) {
|
||||
let dir = tempdir().unwrap();
|
||||
let input = input_path.as_ref().to_path_buf();
|
||||
let output = dir.path().join("output.rbxlx");
|
||||
let output = Some(dir.path().join("output.rbxlx"));
|
||||
|
||||
let options = BuildCommand {
|
||||
project: input,
|
||||
watch: false,
|
||||
plugin: None,
|
||||
output,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,11 @@ use std::{
|
|||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use anyhow::Context;
|
||||
use clap::Parser;
|
||||
use anyhow::{bail, Context};
|
||||
use clap::{CommandFactory, Parser};
|
||||
use fs_err::File;
|
||||
use memofs::Vfs;
|
||||
use roblox_install::RobloxStudio;
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
use crate::serve_session::ServeSession;
|
||||
|
|
@ -16,6 +17,8 @@ use super::resolve_path;
|
|||
|
||||
const UNKNOWN_OUTPUT_KIND_ERR: &str = "Could not detect what kind of file to build. \
|
||||
Expected output file to end in .rbxl, .rbxlx, .rbxm, or .rbxmx.";
|
||||
const UNKNOWN_PLUGIN_KIND_ERR: &str = "Could not detect what kind of file to build. \
|
||||
Expected plugin file to end in .rbxm or .rbxmx.";
|
||||
|
||||
/// Generates a model or place file from the Rojo project.
|
||||
#[derive(Debug, Parser)]
|
||||
|
|
@ -28,7 +31,13 @@ pub struct BuildCommand {
|
|||
///
|
||||
/// Should end in .rbxm, .rbxl, .rbxmx, or .rbxlx.
|
||||
#[clap(long, short)]
|
||||
pub output: PathBuf,
|
||||
pub output: Option<PathBuf>,
|
||||
|
||||
/// Alternative to the output flag that outputs the result in the local plugins folder.
|
||||
///
|
||||
/// Should end in .rbxm or .rbxl.
|
||||
#[clap(long, short)]
|
||||
pub plugin: Option<PathBuf>,
|
||||
|
||||
/// Whether to automatically rebuild when any input files change.
|
||||
#[clap(long)]
|
||||
|
|
@ -37,18 +46,52 @@ pub struct BuildCommand {
|
|||
|
||||
impl BuildCommand {
|
||||
pub fn run(self) -> anyhow::Result<()> {
|
||||
let project_path = resolve_path(&self.project);
|
||||
let (output_path, output_kind) = match (self.output, self.plugin) {
|
||||
(Some(_), Some(_)) => {
|
||||
BuildCommand::command()
|
||||
.error(
|
||||
clap::ErrorKind::ArgumentConflict,
|
||||
"the argument '--output <OUTPUT>' cannot be used with '--plugin <PLUGIN>'",
|
||||
)
|
||||
.exit();
|
||||
}
|
||||
(None, None) => {
|
||||
BuildCommand::command()
|
||||
.error(
|
||||
clap::ErrorKind::MissingRequiredArgument,
|
||||
"one of the following arguments must be provided: \n --output <OUTPUT>\n --plugin <PLUGIN>",
|
||||
)
|
||||
.exit();
|
||||
}
|
||||
(Some(output), None) => {
|
||||
let output_kind =
|
||||
OutputKind::from_output_path(&output).context(UNKNOWN_OUTPUT_KIND_ERR)?;
|
||||
|
||||
let output_kind = detect_output_kind(&self.output).context(UNKNOWN_OUTPUT_KIND_ERR)?;
|
||||
(output, output_kind)
|
||||
}
|
||||
(None, Some(plugin)) => {
|
||||
if plugin.is_absolute() {
|
||||
bail!("plugin flag path cannot be absolute.")
|
||||
}
|
||||
|
||||
let output_kind =
|
||||
OutputKind::from_plugin_path(&plugin).context(UNKNOWN_PLUGIN_KIND_ERR)?;
|
||||
let studio = RobloxStudio::locate()?;
|
||||
|
||||
(studio.plugins_path().join(&plugin), output_kind)
|
||||
}
|
||||
};
|
||||
|
||||
let project_path = resolve_path(&self.project);
|
||||
|
||||
log::trace!("Constructing in-memory filesystem");
|
||||
let vfs = Vfs::new_default();
|
||||
vfs.set_watch_enabled(self.watch);
|
||||
|
||||
let session = ServeSession::new(vfs, &project_path)?;
|
||||
let session = ServeSession::new(vfs, project_path)?;
|
||||
let mut cursor = session.message_queue().cursor();
|
||||
|
||||
write_model(&session, &self.output, output_kind)?;
|
||||
write_model(&session, &output_path, output_kind)?;
|
||||
|
||||
if self.watch {
|
||||
let rt = Runtime::new().unwrap();
|
||||
|
|
@ -58,7 +101,7 @@ impl BuildCommand {
|
|||
let (new_cursor, _patch_set) = rt.block_on(receiver).unwrap();
|
||||
cursor = new_cursor;
|
||||
|
||||
write_model(&session, &self.output, output_kind)?;
|
||||
write_model(&session, &output_path, output_kind)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -86,15 +129,27 @@ enum OutputKind {
|
|||
Rbxl,
|
||||
}
|
||||
|
||||
fn detect_output_kind(output: &Path) -> Option<OutputKind> {
|
||||
let extension = output.extension()?.to_str()?;
|
||||
impl OutputKind {
|
||||
fn from_output_path(output: &Path) -> Option<OutputKind> {
|
||||
let extension = output.extension()?.to_str()?;
|
||||
|
||||
match extension {
|
||||
"rbxlx" => Some(OutputKind::Rbxlx),
|
||||
"rbxmx" => Some(OutputKind::Rbxmx),
|
||||
"rbxl" => Some(OutputKind::Rbxl),
|
||||
"rbxm" => Some(OutputKind::Rbxm),
|
||||
_ => None,
|
||||
match extension {
|
||||
"rbxlx" => Some(OutputKind::Rbxlx),
|
||||
"rbxmx" => Some(OutputKind::Rbxmx),
|
||||
"rbxl" => Some(OutputKind::Rbxl),
|
||||
"rbxm" => Some(OutputKind::Rbxm),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_plugin_path(output: &Path) -> Option<OutputKind> {
|
||||
let extension = output.extension()?.to_str()?;
|
||||
|
||||
match extension {
|
||||
"rbxmx" => Some(OutputKind::Rbxmx),
|
||||
"rbxm" => Some(OutputKind::Rbxm),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::borrow::Borrow;
|
|||
|
||||
use anyhow::{bail, format_err};
|
||||
use rbx_dom_weak::types::{
|
||||
Attributes, CFrame, Color3, Content, Enum, Matrix3, Tags, Variant, VariantType, Vector2,
|
||||
Attributes, CFrame, Color3, Content, Enum, Font, Matrix3, Tags, Variant, VariantType, Vector2,
|
||||
Vector3,
|
||||
};
|
||||
use rbx_reflection::{DataType, PropertyDescriptor};
|
||||
|
|
@ -49,6 +49,7 @@ pub enum AmbiguousValue {
|
|||
Array4([f64; 4]),
|
||||
Array12([f64; 12]),
|
||||
Attributes(Attributes),
|
||||
Font(Font),
|
||||
}
|
||||
|
||||
impl AmbiguousValue {
|
||||
|
|
@ -139,6 +140,8 @@ impl AmbiguousValue {
|
|||
|
||||
(VariantType::Attributes, AmbiguousValue::Attributes(value)) => Ok(value.into()),
|
||||
|
||||
(VariantType::Font, AmbiguousValue::Font(value)) => Ok(value.into()),
|
||||
|
||||
(_, unresolved) => Err(format_err!(
|
||||
"Wrong type of value for property {}.{}. Expected {:?}, got {}",
|
||||
class_name,
|
||||
|
|
@ -176,6 +179,7 @@ impl AmbiguousValue {
|
|||
AmbiguousValue::Array4(_) => "an array of four numbers",
|
||||
AmbiguousValue::Array12(_) => "an array of twelve numbers",
|
||||
AmbiguousValue::Attributes(_) => "an object containing attributes",
|
||||
AmbiguousValue::Font(_) => "an object describing a Font",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -328,4 +332,23 @@ mod test {
|
|||
Variant::Enum(Enum::from_u32(1)),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn font() {
|
||||
use rbx_dom_weak::types::{FontStyle, FontWeight};
|
||||
|
||||
assert_eq!(
|
||||
resolve(
|
||||
"TextLabel",
|
||||
"FontFace",
|
||||
r#"{"family": "rbxasset://fonts/families/RobotoMono.json", "weight": "Thin", "style": "Normal"}"#
|
||||
),
|
||||
Variant::Font(Font {
|
||||
family: "rbxasset://fonts/families/RobotoMono.json".into(),
|
||||
weight: FontWeight::Thin,
|
||||
style: FontStyle::Normal,
|
||||
cached_face_id: None,
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue