Skip to content

Commit

Permalink
feat(cli): added serve command
Browse files Browse the repository at this point in the history
  • Loading branch information
arctic-hen7 committed Dec 28, 2021
1 parent 02d243a commit 7ec3b9d
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 10 deletions.
2 changes: 2 additions & 0 deletions packages/tribble/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ fmterr = "0.1"
clap = { version = "=3.0.0-beta.5", features = [ "color" ] }
include_dir = "0.6"
fs_extra = "1"
warp = "0.3"
tokio = { version = "1", features = [ "macros", "rt-multi-thread" ] }
29 changes: 21 additions & 8 deletions packages/tribble/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod delete;
mod errors;
mod options;
mod prep;
mod serve;

use crate::delete::delete_dist_dir;
use crate::delete::delete_tribble_dir;
Expand All @@ -18,17 +19,18 @@ use std::path::PathBuf;
pub const TRIBBLE_VERSION: &str = env!("CARGO_PKG_VERSION");

// All this does is run the program and terminate with the acquired exit code
fn main() {
#[tokio::main]
async fn main() {
// In development, we'll test one of the examples
if cfg!(debug_assertions) {
env::set_current_dir("../../examples").unwrap();
}
let exit_code = real_main();
let exit_code = real_main().await;
std::process::exit(exit_code)
}

// This manages error handling and returns a definite exit code to terminate with
fn real_main() -> i32 {
async fn real_main() -> i32 {
// Get the working directory
let dir = env::current_dir();
let dir = match dir {
Expand All @@ -41,7 +43,7 @@ fn real_main() -> i32 {
return 1;
}
};
let res = core(dir);
let res = core(dir).await;
match res {
// If it worked, we pass the executed command's exit code through
Ok(exit_code) => exit_code,
Expand All @@ -53,7 +55,7 @@ fn real_main() -> i32 {
}
}

fn core(dir: PathBuf) -> Result<i32, Error> {
async fn core(dir: PathBuf) -> Result<i32, Error> {
// Parse the CLI options with `clap`
let opts: Opts = Opts::parse();
// Set the `TRIBBLE_CONF` environment variable to what the user provided (used by the static exporting binary)
Expand All @@ -68,9 +70,20 @@ fn core(dir: PathBuf) -> Result<i32, Error> {
// Build the user's app
crate::build::build(dir)?
}
Subcommand::Serve => {
//
// TODO Serve the user's app
Subcommand::Serve {
no_build,
host,
port,
} => {
// Build the user's app (unless `--no-build` was provided)
if !no_build {
let build_exit_code = crate::build::build(dir.clone())?;
if build_exit_code != 0 {
return Ok(build_exit_code);
}
}
// Serve the user's app
crate::serve::serve(dir, host, port).await;
0
}
Subcommand::Clean => {
Expand Down
15 changes: 13 additions & 2 deletions packages/tribble/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,21 @@ pub struct Opts {

#[derive(Parser)]
pub enum Subcommand {
/// Builds your Tribble workflows. This is called by `tribble serve` automatically
/// Builds your Tribble workflows. This is called by `tribble serve` automatically. Note that this is always in release
/// mode, Tribble has no other mode
Build,
/// Serves your Tribble workflows locally for development
Serve,
Serve {
/// Don't build your app (if you haven't already run `tribble build`, you'll get a blank page in your browser)
#[clap(long, short)]
no_build: bool,
/// Where to host Tribble
#[clap(long, default_value = "127.0.0.1")]
host: String,
/// The port to host Tribble on
#[clap(long, default_value = "8080")]
port: u16,
},
/// Builds your Tribble workflows for release deployment
Deploy,
/// Deletes the `.tribble/` directory in the case of a corruption
Expand Down
20 changes: 20 additions & 0 deletions packages/tribble/src/serve.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use std::net::SocketAddr;
use std::path::PathBuf;
use warp::Filter;

/// Serves the generated app from `.tribble/dist/`. This expects the app to already have been built.
pub async fn serve(dir: PathBuf, host: String, port: u16) {
let dir = dir.join(".tribble/dist");
// We actually don't have to worry about HTML file extensions at all
let files = warp::any().and(warp::fs::dir(dir));
// Parse `localhost` into `127.0.0.1` (picky Rust `std`)
let host = if host == "localhost" {
"127.0.0.1".to_string()
} else {
host
};
// Parse the host and port into an address
let addr: SocketAddr = format!("{}:{}", host, port).parse().unwrap();

warp::serve(files).run(addr).await
}

0 comments on commit 7ec3b9d

Please sign in to comment.