Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement rojo open #622

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/cli/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::serve_session::ServeSession;

use super::resolve_path;

const UNKNOWN_OUTPUT_KIND_ERR: &str = "Could not detect what kind of file to build. \
pub(in crate::cli) 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.";

/// Generates a model or place file from the Rojo project.
Expand Down Expand Up @@ -72,7 +72,7 @@ impl BuildCommand {

/// The different kinds of output that Rojo can build to.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum OutputKind {
pub(in crate::cli) enum OutputKind {
/// An XML model file.
Rbxmx,

Expand All @@ -86,7 +86,7 @@ enum OutputKind {
Rbxl,
}

fn detect_output_kind(output: &Path) -> Option<OutputKind> {
pub(in crate::cli) fn detect_output_kind(output: &Path) -> Option<OutputKind> {
let extension = output.extension()?.to_str()?;

match extension {
Expand All @@ -103,7 +103,7 @@ fn xml_encode_config() -> rbx_xml::EncodeOptions {
}

#[profiling::function]
fn write_model(
pub(in crate::cli) fn write_model(
session: &ServeSession,
output: &Path,
output_kind: OutputKind,
Expand Down
4 changes: 4 additions & 0 deletions src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod build;
mod doc;
mod fmt_project;
mod init;
mod open;
mod plugin;
mod serve;
mod sourcemap;
Expand All @@ -18,6 +19,7 @@ pub use self::build::BuildCommand;
pub use self::doc::DocCommand;
pub use self::fmt_project::FmtProjectCommand;
pub use self::init::{InitCommand, InitKind};
use self::open::OpenCommand;
pub use self::plugin::{PluginCommand, PluginSubcommand};
pub use self::serve::ServeCommand;
pub use self::sourcemap::SourcemapCommand;
Expand Down Expand Up @@ -46,6 +48,7 @@ impl Options {
Subcommand::FmtProject(subcommand) => subcommand.run(),
Subcommand::Doc(subcommand) => subcommand.run(),
Subcommand::Plugin(subcommand) => subcommand.run(),
Subcommand::Open(subcommand) => subcommand.run(self.global),
}
}
}
Expand Down Expand Up @@ -119,6 +122,7 @@ pub enum Subcommand {
FmtProject(FmtProjectCommand),
Doc(DocCommand),
Plugin(PluginCommand),
Open(OpenCommand),
}

pub(super) fn resolve_path(path: &Path) -> Cow<'_, Path> {
Expand Down
75 changes: 75 additions & 0 deletions src/cli/open.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use anyhow::{Context, Ok};
use clap::Parser;
use memofs::Vfs;
use roblox_install::RobloxStudio;

use crate::{
cli::{
build::{detect_output_kind, write_model, UNKNOWN_OUTPUT_KIND_ERR},
plugin::install_plugin,
serve::{show_start_message, DEFAULT_BIND_ADDRESS, DEFAULT_PORT},
},
serve_session::ServeSession,
web::LiveServer,
PROJECT_FILENAME,
};
use std::{env, net::IpAddr, path::PathBuf, sync::Arc};

use super::GlobalOptions;

#[derive(Debug, Parser)]
pub struct OpenCommand {
/// Path to the project file to serve from. Defaults to default.project.json.
#[clap(value_parser)]
pub project: Option<PathBuf>,

// Path to an output place to build and serve to. Will be created automatically
/// if it doesn't exist.
#[clap(long)]
pub output: PathBuf,

/// The IP address to listen on. Defaults to `127.0.0.1`.
#[clap(long)]
pub address: Option<IpAddr>,

/// The port to listen on. Defaults to the project's preference, or `34872` if
/// it has none.
#[clap(long)]
pub port: Option<u16>,
}

impl OpenCommand {
pub fn run(self, global: GlobalOptions) -> anyhow::Result<()> {
let project = self
.project
.unwrap_or_else(|| env::current_dir().unwrap().join(PROJECT_FILENAME));
let output_kind = detect_output_kind(&self.output).context(UNKNOWN_OUTPUT_KIND_ERR)?;

log::trace!("Constructing in-memory filesystem");
let vfs = Vfs::new_default();
vfs.set_watch_enabled(false);
Yumacide marked this conversation as resolved.
Show resolved Hide resolved
let session = ServeSession::new(vfs, &project)?;

if !self.output.exists() {
write_model(&session, &self.output, output_kind)?;
}
install_plugin().unwrap();

opener::open(&self.output).expect("Could not open place in Roblox Studio");

let ip = self
.address
.or_else(|| session.serve_address())
.unwrap_or_else(|| DEFAULT_BIND_ADDRESS.into());
let port = self
Yumacide marked this conversation as resolved.
Show resolved Hide resolved
.port
.or_else(|| session.project_port())
.unwrap_or(DEFAULT_PORT);
let server = LiveServer::new(Arc::new(session));

show_start_message(ip, port, global.color.into())?;
server.start((ip, port).into());

Ok(())
}
}
2 changes: 1 addition & 1 deletion src/cli/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl PluginSubcommand {
}
}

fn install_plugin() -> anyhow::Result<()> {
pub(in crate::cli) fn install_plugin() -> anyhow::Result<()> {
let plugin_snapshot: VfsSnapshot = bincode::deserialize(PLUGIN_BINCODE)
.expect("Rojo's plugin was not properly packed into Rojo's binary");

Expand Down
10 changes: 7 additions & 3 deletions src/cli/serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use crate::{serve_session::ServeSession, web::LiveServer};

use super::{resolve_path, GlobalOptions};

const DEFAULT_BIND_ADDRESS: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1);
const DEFAULT_PORT: u16 = 34872;
pub(in crate::cli) const DEFAULT_BIND_ADDRESS: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1);
pub(in crate::cli) const DEFAULT_PORT: u16 = 34872;

/// Expose a Rojo project to the Rojo Studio plugin.
#[derive(Debug, Parser)]
Expand Down Expand Up @@ -60,7 +60,11 @@ impl ServeCommand {
}
}

fn show_start_message(bind_address: IpAddr, port: u16, color: ColorChoice) -> io::Result<()> {
pub(in crate::cli) fn show_start_message(
bind_address: IpAddr,
port: u16,
color: ColorChoice,
) -> io::Result<()> {
let mut green = ColorSpec::new();
green.set_fg(Some(Color::Green)).set_bold(true);

Expand Down
2 changes: 1 addition & 1 deletion src/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use thiserror::Error;

use crate::{glob::Glob, resolution::UnresolvedValue};

static PROJECT_FILENAME: &str = "default.project.json";
pub(crate) static PROJECT_FILENAME: &str = "default.project.json";

/// Error type returned by any function that handles projects.
#[derive(Debug, Error)]
Expand Down