mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-23 22:11:38 +00:00
Prototype server plugins, add example MoonScript plugin
This commit is contained in:
parent
6fcb895d70
commit
4b9fc137f8
9 changed files with 189 additions and 2 deletions
|
|
@ -20,6 +20,7 @@ default = []
|
|||
bundle-plugin = []
|
||||
|
||||
[dependencies]
|
||||
bincode = "1.0"
|
||||
clap = "2.27"
|
||||
csv = "1.0"
|
||||
env_logger = "0.5"
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use std::{
|
|||
collections::HashMap,
|
||||
fmt,
|
||||
path::{Path, PathBuf},
|
||||
process::{Command, Stdio},
|
||||
str,
|
||||
};
|
||||
|
||||
|
|
@ -33,6 +34,13 @@ use crate::{
|
|||
rbx_session::{MetadataPerPath, MetadataPerInstance},
|
||||
};
|
||||
|
||||
// In a real plugin implementation, this would be part of the project file.
|
||||
// Should the executable name be limited to try to prevent malicious projects
|
||||
// from executing arbitrary code?
|
||||
static PLUGINS: [(&str, &str); 1] = [
|
||||
("moon", "target/debug/rojo-plugin-moonscript"),
|
||||
];
|
||||
|
||||
const INIT_MODULE_NAME: &str = "init.lua";
|
||||
const INIT_SERVER_NAME: &str = "init.server.lua";
|
||||
const INIT_CLIENT_NAME: &str = "init.client.lua";
|
||||
|
|
@ -246,7 +254,65 @@ fn snapshot_imfs_file<'source>(
|
|||
Some("txt") => snapshot_txt_file(file)?,
|
||||
Some("rbxmx") => snapshot_xml_model_file(file)?,
|
||||
Some("rbxm") => snapshot_binary_model_file(file)?,
|
||||
Some(_) | None => return Ok(None),
|
||||
// In a real plugin implementation, plugins would probably want to
|
||||
// execute before any of the builtin instance routines.
|
||||
//
|
||||
// Alternatively, maybe we want to run the builtin routines and send the
|
||||
// snapshot generated by that routine as well as the original file? That
|
||||
// would open the door to make plugins that transform instances to do
|
||||
// things like add source headers or optimize code without having to
|
||||
// create another kind of plugin.
|
||||
Some(unknown_ext) => {
|
||||
let mut result = None;
|
||||
|
||||
for (plugin_ext, plugin_path) in &PLUGINS {
|
||||
if plugin_ext == &unknown_ext {
|
||||
let mut child = Command::new(plugin_path)
|
||||
// This argument is standard for telling processes to
|
||||
// read from stdin, we can pass it as a courtesy even
|
||||
// though I bet all plugin processes will be
|
||||
// purpose-built to correctly deal with structured input
|
||||
// from Rojo
|
||||
.arg("--")
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.expect("Could not spawn plugin process");
|
||||
|
||||
{
|
||||
let stdin = child.stdin.as_mut().unwrap();
|
||||
// We're using bincode here since it makes Vec<u8>
|
||||
// serialize more cleanly than JSON, but we could use
|
||||
// whatever.
|
||||
bincode::serialize_into(stdin, file)
|
||||
.expect("Could not serialize file into plugin stdin");
|
||||
}
|
||||
|
||||
let output = child.wait_with_output()
|
||||
.expect("Could not wait for plugin process output");
|
||||
|
||||
assert!(output.status.success());
|
||||
|
||||
// I'm accepting JSON for the output because bincode doesn't
|
||||
// implement all of the features needed to actually
|
||||
// deserialize a RbxSnapshotInstance I guess.
|
||||
//
|
||||
// Whatever format is used for plugins, it should probably
|
||||
// be consistent between input/output.
|
||||
//
|
||||
// This also doesn't account for representing failure or a
|
||||
// plugin returning no instance at all.
|
||||
let snapshot: RbxSnapshotInstance<'static> = serde_json::from_slice(&output.stdout)
|
||||
.expect("Could not deserialize plugin output");
|
||||
|
||||
result = Some(snapshot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
},
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
if let Some(snapshot) = maybe_snapshot.as_mut() {
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ impl InstanceChanges {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct RbxSnapshotInstance<'a> {
|
||||
pub name: Cow<'a, str>,
|
||||
pub class_name: Cow<'a, str>,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue