-
Notifications
You must be signed in to change notification settings - Fork 87
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9e5afd1
commit 66dc282
Showing
8 changed files
with
181 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,82 @@ | ||
use std::path::PathBuf; | ||
use console::{style, Emoji}; | ||
use crate::cmd::run_stage; | ||
use crate::errors::*; | ||
|
||
/// Builds the subcrates to get a directory that we can serve. | ||
pub fn build(dir: PathBuf, prog_args: &[String]) -> Result<()> { | ||
todo!("build command") | ||
// Emojis for stages | ||
static GENERATING: Emoji<'_, '_> = Emoji("🔨", ""); | ||
static BUILDING: Emoji<'_, '_> = Emoji("🏗️ ", ""); // Yes, there's a space here, for some reason it's needed... | ||
static FINALIZING: Emoji<'_, '_> = Emoji("📦", ""); | ||
|
||
/// Returns the exit code if it's non-zero. | ||
macro_rules! handle_exit_code { | ||
($code:expr) => { | ||
let code = $code; | ||
if code != 0 { | ||
return Ok(code); | ||
} | ||
}; | ||
} | ||
|
||
/// Actually builds the user's code, program arguments having been interpreted. | ||
fn build_internal(dir: PathBuf) -> Result<i32> { | ||
let mut target = dir; | ||
target.extend([".perseus"]); | ||
|
||
// Static generation | ||
handle_exit_code!(run_stage( | ||
vec![ | ||
"cargo run" | ||
], | ||
&target, | ||
format!( | ||
"{} {} Generating your app", | ||
style("[1/3]").bold().dim(), | ||
GENERATING | ||
) | ||
)?); | ||
// WASM building | ||
handle_exit_code!(run_stage( | ||
vec![ | ||
"wasm-pack build --target web", | ||
// Move the `pkg/` directory into `dist/pkg/` | ||
"rm -rf dist/pkg", | ||
"mv pkg/ dist/", | ||
], | ||
&target, | ||
format!( | ||
"{} {} Building your app to WASM", | ||
style("[2/3]").bold().dim(), | ||
BUILDING | ||
) | ||
)?); | ||
// JS bundle generation | ||
handle_exit_code!(run_stage( | ||
vec![ | ||
"rollup main.js --format iife --file dist/pkg/bundle.js" | ||
], | ||
&target, | ||
format!( | ||
"{} {} Finalizing bundle", | ||
style("[3/3]").bold().dim(), | ||
FINALIZING | ||
) | ||
)?); | ||
|
||
Ok(0) | ||
} | ||
|
||
/// Builds the subcrates to get a directory that we can serve. Returns an exit code. | ||
pub fn build(dir: PathBuf, prog_args: &[String]) -> Result<i32> { | ||
// TODO support watching files | ||
// If we should watch for file changes, do so | ||
let should_watch = prog_args.get(1); | ||
let dflt_watch_path = ".".to_string(); | ||
let _watch_path = prog_args.get(2).unwrap_or(&dflt_watch_path); | ||
if should_watch == Some(&"-w".to_string()) || should_watch == Some(&"--watch".to_string()) { | ||
todo!("watching not yet supported, try a tool like 'entr'"); | ||
} | ||
let exit_code = build_internal(dir.clone())?; | ||
|
||
Ok(exit_code) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
use std::process::Command; | ||
use std::path::Path; | ||
use std::io::Write; | ||
use indicatif::{ProgressBar, ProgressStyle}; | ||
use console::Emoji; | ||
use crate::errors::*; | ||
|
||
// Some useful emojis | ||
static SUCCESS: Emoji<'_, '_> = Emoji("✅", "success!"); | ||
static FAILURE: Emoji<'_, '_> = Emoji("❌", "failed!"); | ||
|
||
/// Runs the given command conveniently, returning the exit code. Notably, this parses the given command by separating it on spaces. | ||
pub fn run_cmd(raw_cmd: String, dir: &Path, pre_dump: impl Fn()) -> Result<i32> { | ||
let mut cmd_args: Vec<&str> = raw_cmd.split(' ').collect(); | ||
let cmd = cmd_args.remove(0); | ||
|
||
// This will NOT pipe output/errors to the console | ||
let output = Command::new(&cmd) | ||
.args(cmd_args) | ||
.current_dir(dir) | ||
.output() | ||
.map_err(|err| ErrorKind::CmdExecFailed(raw_cmd.clone(), err.to_string()))?; | ||
|
||
let exit_code = match output.status.code() { | ||
Some(exit_code) => exit_code, // If we have an exit code, use it | ||
None if output.status.success() => 0, // If we don't, but we know the command succeeded, return 0 (success code) | ||
None => 1, // If we don't know an exit code but we know that the command failed, return 1 (general error code) | ||
}; | ||
|
||
// Print `stderr` only if there's something therein and the exit code is non-zero | ||
if !output.stderr.is_empty() && exit_code != 0 { | ||
pre_dump(); | ||
std::io::stderr().write_all(&output.stderr).unwrap(); | ||
} | ||
|
||
Ok(exit_code) | ||
} | ||
|
||
pub fn run_stage(cmds: Vec<&str>, target: &Path, message: String) -> Result<i32> { | ||
// Tell the user about the stage with a nice progress bar | ||
let spinner = ProgressBar::new_spinner(); | ||
spinner.set_style( | ||
ProgressStyle::default_spinner() | ||
.tick_chars("⠁⠂⠄⡀⢀⠠⠐⠈ ") | ||
); | ||
spinner.set_message(format!("{}...", message)); | ||
// Tick the spinner every 50 milliseconds | ||
spinner.enable_steady_tick(50); | ||
|
||
// Run the commands | ||
for cmd in cmds { | ||
// We make sure all commands run in the target directory ('.perseus/' itself) | ||
let exit_code = run_cmd(cmd.to_string(), target, || { | ||
// We're done, we'll write a more permanent version of the message | ||
spinner.finish_with_message(format!( | ||
"{}...{}", | ||
message, | ||
FAILURE | ||
)) | ||
})?; | ||
// If we have a non-zero exit code, we should NOT continue (stderr has been written to the console already) | ||
if exit_code != 0 { | ||
return Ok(1); | ||
} | ||
} | ||
|
||
// We're done, we'll write a more permanent version of the message | ||
spinner.finish_with_message(format!( | ||
"{}...{}", | ||
message, | ||
SUCCESS | ||
)); | ||
|
||
Ok(0) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ mod prepare; | |
pub mod errors; | ||
mod build; | ||
mod serve; | ||
mod cmd; | ||
|
||
use errors::*; | ||
use std::fs; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters