forked from rojo-rbx/rojo
Install plugin from CLI (#304)
* add install command * cargo fmt * filter spec files * Update src/cli/plugin.rs Co-Authored-By: Lucien Greathouse <me@lpghatguy.com> * Update src/cli/plugin.rs Co-Authored-By: Lucien Greathouse <me@lpghatguy.com> * fix comments * encode plugin with rbx_binary * update build script * refactor pathbuf error into io error * fix rojo typo * remove snafu * Update `snapshot_from_fs_path` * Print `rerun-if-changed` even for directories, in order to run the build.rs script when files are added. * Switch `filter_map` loop to a regular for loop. I like the FP-style iterator stuff in Rust, but I think Result handling is easier in a normal loop. Also, I don't believe the result of read_dir implements `ExactSizedIterator`, so some of the wins of map+collect aren't there. * Replace Result::unwrap with ? in build.rs * Simplify error handling code in runtime * Checkout with submodules Co-authored-by: Lucien Greathouse <me@lpghatguy.com>
This commit is contained in:
@@ -12,6 +12,7 @@ fn run(global: GlobalOptions, subcommand: Subcommand) -> Result<(), Box<dyn Erro
|
||||
Subcommand::Build(build_options) => cli::build(build_options)?,
|
||||
Subcommand::Upload(upload_options) => cli::upload(upload_options)?,
|
||||
Subcommand::Doc => cli::doc()?,
|
||||
Subcommand::Plugin(plugin_options) => cli::plugin(plugin_options)?,
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
mod build;
|
||||
mod doc;
|
||||
mod init;
|
||||
mod plugin;
|
||||
mod serve;
|
||||
mod upload;
|
||||
|
||||
@@ -21,6 +22,7 @@ use thiserror::Error;
|
||||
pub use self::build::*;
|
||||
pub use self::doc::*;
|
||||
pub use self::init::*;
|
||||
pub use self::plugin::*;
|
||||
pub use self::serve::*;
|
||||
pub use self::upload::*;
|
||||
|
||||
@@ -111,6 +113,9 @@ pub enum Subcommand {
|
||||
|
||||
/// Open Rojo's documentation in your browser.
|
||||
Doc,
|
||||
|
||||
/// Manages Rojo's Roblox Studio plugin.
|
||||
Plugin(PluginCommand),
|
||||
}
|
||||
|
||||
/// Initializes a new Rojo project.
|
||||
@@ -287,3 +292,21 @@ fn resolve_path(path: &Path) -> Cow<'_, Path> {
|
||||
Cow::Owned(env::current_dir().unwrap().join(path))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum PluginSubcommand {
|
||||
/// Install the plugin in Roblox Studio's plugins folder. If the plugin is
|
||||
/// already installed, installing it again will overwrite the current plugin
|
||||
/// file.
|
||||
Install,
|
||||
|
||||
/// Removes the plugin if it is installed.
|
||||
Uninstall,
|
||||
}
|
||||
|
||||
/// Install Rojo's plugin.
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct PluginCommand {
|
||||
#[structopt(subcommand)]
|
||||
subcommand: PluginSubcommand,
|
||||
}
|
||||
|
||||
70
src/cli/plugin.rs
Normal file
70
src/cli/plugin.rs
Normal file
@@ -0,0 +1,70 @@
|
||||
use std::{
|
||||
fs::{self, File},
|
||||
io::BufWriter,
|
||||
};
|
||||
|
||||
use anyhow::Result;
|
||||
use memofs::{InMemoryFs, Vfs, VfsSnapshot};
|
||||
use roblox_install::RobloxStudio;
|
||||
|
||||
use crate::{
|
||||
cli::{PluginCommand, PluginSubcommand},
|
||||
serve_session::ServeSession,
|
||||
};
|
||||
|
||||
static PLUGIN_BINCODE: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/plugin.bincode"));
|
||||
static PLUGIN_FILE_NAME: &str = "RojoManagedPlugin.rbxm";
|
||||
|
||||
pub fn plugin(options: PluginCommand) -> Result<()> {
|
||||
match options.subcommand {
|
||||
PluginSubcommand::Install => install_plugin(),
|
||||
PluginSubcommand::Uninstall => uninstall_plugin(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn install_plugin() -> Result<()> {
|
||||
let plugin_snapshot: VfsSnapshot = bincode::deserialize(PLUGIN_BINCODE)
|
||||
.expect("Rojo's plugin was not properly packed into Rojo's binary");
|
||||
|
||||
let studio = RobloxStudio::locate()?;
|
||||
|
||||
let plugins_folder_path = studio.plugins_path();
|
||||
|
||||
if !plugins_folder_path.exists() {
|
||||
log::debug!("Creating Roblox Studio plugins folder");
|
||||
fs::create_dir(plugins_folder_path)?;
|
||||
}
|
||||
|
||||
let mut in_memory_fs = InMemoryFs::new();
|
||||
in_memory_fs.load_snapshot("plugin", plugin_snapshot)?;
|
||||
|
||||
let vfs = Vfs::new(in_memory_fs);
|
||||
let session = ServeSession::new(vfs, "plugin")?;
|
||||
|
||||
let plugin_path = plugins_folder_path.join(PLUGIN_FILE_NAME);
|
||||
log::debug!("Writing plugin to {}", plugin_path.display());
|
||||
|
||||
let mut file = BufWriter::new(File::create(plugin_path)?);
|
||||
|
||||
let tree = session.tree();
|
||||
let root_id = tree.get_root_id();
|
||||
|
||||
rbx_binary::encode(tree.inner(), &[root_id], &mut file)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn uninstall_plugin() -> Result<()> {
|
||||
let studio = RobloxStudio::locate()?;
|
||||
|
||||
let plugin_path = studio.plugins_path().join(PLUGIN_FILE_NAME);
|
||||
|
||||
if plugin_path.exists() {
|
||||
log::debug!("Removing existing plugin from {}", plugin_path.display());
|
||||
fs::remove_file(plugin_path)?;
|
||||
} else {
|
||||
log::debug!("Plugin not installed at {}", plugin_path.display());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user