From 88d2d1f19353138b7a101b34d5b8b48ded22e031 Mon Sep 17 00:00:00 2001 From: Lucien Greathouse Date: Fri, 10 Jun 2022 03:15:44 -0400 Subject: [PATCH] Stub out a command sorta like rostar unpack --- src/cli/mod.rs | 4 +++ src/cli/unpack.rs | 65 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 src/cli/unpack.rs diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 36b32940..5aee7cf0 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -7,6 +7,7 @@ mod init; mod plugin; mod serve; mod sourcemap; +mod unpack; mod upload; use std::{borrow::Cow, env, path::Path, str::FromStr}; @@ -21,6 +22,7 @@ pub use self::init::{InitCommand, InitKind}; pub use self::plugin::{PluginCommand, PluginSubcommand}; pub use self::serve::ServeCommand; pub use self::sourcemap::SourcemapCommand; +pub use self::unpack::UnpackCommand; pub use self::upload::UploadCommand; /// Command line options that Rojo accepts, defined using the clap crate. @@ -46,6 +48,7 @@ impl Options { Subcommand::FmtProject(subcommand) => subcommand.run(), Subcommand::Doc(subcommand) => subcommand.run(), Subcommand::Plugin(subcommand) => subcommand.run(), + Subcommand::Unpack(subcommand) => subcommand.run(), } } } @@ -119,6 +122,7 @@ pub enum Subcommand { FmtProject(FmtProjectCommand), Doc(DocCommand), Plugin(PluginCommand), + Unpack(UnpackCommand), } pub(super) fn resolve_path(path: &Path) -> Cow<'_, Path> { diff --git a/src/cli/unpack.rs b/src/cli/unpack.rs new file mode 100644 index 00000000..1eb0d97e --- /dev/null +++ b/src/cli/unpack.rs @@ -0,0 +1,65 @@ +use std::{io::BufReader, path::PathBuf}; + +use anyhow::bail; +use clap::Parser; +use fs_err::File; +use rbx_dom_weak::{Instance, WeakDom}; + +use crate::{Project, ProjectNode}; + +use super::resolve_path; + +/// Unpack a Roblox place file into an existing Rojo project. +#[derive(Debug, Parser)] +pub struct UnpackCommand { + /// Path to the project to unpack. Defaults to the current directory. + #[clap(long, default_value = "")] + pub project: PathBuf, + + /// Path to the place to unpack from. + pub place: PathBuf, +} + +impl UnpackCommand { + pub fn run(self) -> anyhow::Result<()> { + let project_path = resolve_path(&self.project); + let project = match Project::load_fuzzy(&project_path)? { + Some(project) => project, + None => bail!("No project file was found; rojo unpack requires a project file."), + }; + + let place_ext = self + .place + .extension() + .and_then(|ext| ext.to_str()) + .map(|ext| ext.to_lowercase()); + + let file = BufReader::new(File::open(&self.place)?); + + let dom = match place_ext.as_deref() { + Some("rbxl") => rbx_binary::from_reader(file)?, + Some("rbxlx") => rbx_xml::from_reader_default(file)?, + Some(_) | None => bail!("Place files must end in .rbxl or .rbxlx"), + }; + + let context = Context { project, dom }; + context.unpack(); + + Ok(()) + } +} + +struct Context { + project: Project, + dom: WeakDom, +} + +impl Context { + fn unpack(&self) { + self.unpack_node(&self.project.tree, self.dom.root()); + } + + fn unpack_node(&self, node: &ProjectNode, instance: &Instance) { + // TODO + } +}