diff --git a/src/bindgen.rs b/src/bindgen.rs index d45a4dcad..f4d427a84 100644 --- a/src/bindgen.rs +++ b/src/bindgen.rs @@ -1,16 +1,12 @@ -use console::style; use emoji; use error::Error; +use progressbar::Step; use std::process::Command; use PBAR; -pub fn cargo_install_wasm_bindgen() -> Result<(), Error> { - let step = format!( - "{} {}Installing WASM-bindgen...", - style("[6/7]").bold().dim(), - emoji::DOWN_ARROW - ); - let pb = PBAR.message(&step); +pub fn cargo_install_wasm_bindgen(step: &Step) -> Result<(), Error> { + let msg = format!("{}Installing WASM-bindgen...", emoji::DOWN_ARROW); + let pb = PBAR.step(step, &msg); let output = Command::new("cargo") .arg("install") .arg("wasm-bindgen-cli") @@ -33,14 +29,11 @@ pub fn wasm_bindgen_build( path: &str, name: &str, disable_dts: bool, - target: String, + target: &str, + step: &Step, ) -> Result<(), Error> { - let step = format!( - "{} {}Running WASM-bindgen...", - style("[7/7]").bold().dim(), - emoji::RUNNER - ); - let pb = PBAR.message(&step); + let msg = format!("{}Running WASM-bindgen...", emoji::RUNNER); + let pb = PBAR.step(step, &msg); let binary_name = name.replace("-", "_"); let wasm_path = format!("target/wasm32-unknown-unknown/release/{}.wasm", binary_name); @@ -50,7 +43,7 @@ pub fn wasm_bindgen_build( "--no-typescript" }; - let target_arg = match target.as_str() { + let target_arg = match target { "nodejs" => "--nodejs", _ => "--browser", }; diff --git a/src/build.rs b/src/build.rs index 9793e9014..e8d043380 100644 --- a/src/build.rs +++ b/src/build.rs @@ -1,16 +1,12 @@ -use console::style; use emoji; use error::Error; +use progressbar::Step; use std::process::Command; use PBAR; -pub fn rustup_add_wasm_target() -> Result<(), Error> { - let step = format!( - "{} {}Adding WASM target...", - style("[1/7]").bold().dim(), - emoji::TARGET - ); - let pb = PBAR.message(&step); +pub fn rustup_add_wasm_target(step: &Step) -> Result<(), Error> { + let msg = format!("{}Adding WASM target...", emoji::TARGET); + let pb = PBAR.step(step, &msg); let output = Command::new("rustup") .arg("target") .arg("add") @@ -25,13 +21,9 @@ pub fn rustup_add_wasm_target() -> Result<(), Error> { } } -pub fn cargo_build_wasm(path: &str) -> Result<(), Error> { - let step = format!( - "{} {}Compiling to WASM...", - style("[2/7]").bold().dim(), - emoji::CYCLONE - ); - let pb = PBAR.message(&step); +pub fn cargo_build_wasm(path: &str, step: &Step) -> Result<(), Error> { + let msg = format!("{}Compiling to WASM...", emoji::CYCLONE); + let pb = PBAR.step(step, &msg); let output = Command::new("cargo") .current_dir(path) .arg("build") diff --git a/src/command.rs b/src/command.rs index 4f6023dfe..0eacfda1a 100644 --- a/src/command.rs +++ b/src/command.rs @@ -1,11 +1,11 @@ use bindgen; use build; -use console::style; use emoji; use error::Error; use indicatif::HumanDuration; use manifest; use npm; +use progressbar::Step; #[allow(unused)] use readme; use slog::Logger; @@ -24,6 +24,10 @@ pub enum Command { #[structopt(long = "scope", short = "s")] scope: Option, + #[structopt(long = "--skip-build")] + /// Do not build, only update metadata + skip_build: bool, + #[structopt(long = "no-typescript")] /// By default a *.d.ts file is generated for the generated JS file, but /// this flag will disable generating this TypeScript file. @@ -82,19 +86,21 @@ pub fn run_wasm_pack(command: Command, log: &Logger) -> result::Result<(), Error Command::Init { path, scope, + skip_build, disable_dts, target, } => { info!(&log, "Running init command..."); info!( &log, - "Path: {:?}, Scope: {:?}, Disable Dts: {}, Target: {}", + "Path: {:?}, Scope: {:?}, Skip build: {}, Disable Dts: {}, Target: {}", &path, &scope, + &skip_build, &disable_dts, &target ); - init(path, scope, disable_dts, target, &log) + Init::new(path, scope, skip_build, disable_dts, target).process(&log) } Command::Pack { path } => { info!(&log, "Running pack command..."); @@ -145,111 +151,202 @@ pub fn run_wasm_pack(command: Command, log: &Logger) -> result::Result<(), Error // quicli::prelude::* imports a different result struct which gets // precedence over the std::result::Result, so have had to specify // the correct type here. -pub fn create_pkg_dir(path: &str) -> result::Result<(), Error> { - let step = format!( - "{} {}Creating a pkg directory...", - style("[3/7]").bold().dim(), - emoji::FOLDER - ); - let pb = PBAR.message(&step); +pub fn create_pkg_dir(path: &str, step: &Step) -> result::Result<(), Error> { + let msg = format!("{}Creating a pkg directory...", emoji::FOLDER); + let pb = PBAR.step(step, &msg); let pkg_dir_path = format!("{}/pkg", path); fs::create_dir_all(pkg_dir_path)?; pb.finish(); Ok(()) } -fn init( - path: Option, +struct Init { + crate_path: String, scope: Option, + skip_build: bool, disable_dts: bool, target: String, - log: &Logger, -) -> result::Result<(), Error> { - let started = Instant::now(); - - let crate_path = set_crate_path(path); - - info!(&log, "Adding wasm-target..."); - build::rustup_add_wasm_target()?; - info!(&log, "Adding wasm-target was successful."); - - info!(&log, "Building wasm..."); - build::cargo_build_wasm(&crate_path)?; - - #[cfg(not(target_os = "windows"))] - info!( - &log, - "wasm built at {}/target/wasm32-unknown-unknown/release.", &crate_path - ); - #[cfg(target_os = "windows")] - info!( - &log, - "wasm built at {}\\target\\wasm32-unknown-unknown\\release.", &crate_path - ); + crate_name: Option, +} - info!(&log, "Creating a pkg directory..."); - create_pkg_dir(&crate_path)?; - info!(&log, "Created a pkg directory at {}.", &crate_path); +impl Init { + pub fn new( + path: Option, + scope: Option, + skip_build: bool, + disable_dts: bool, + target: String, + ) -> Init { + Init { + crate_path: set_crate_path(path), + scope, + skip_build, + disable_dts, + target, + crate_name: None, + } + } + pub fn process(&mut self, log: &Logger) -> result::Result<(), Error> { + let steps: Vec result::Result<(), Error>> = + if self.skip_build { + vec![ + Init::step_create_dir, + Init::step_create_json, + Init::step_copy_readme, + ] + } else { + vec![ + Init::step_add_wasm_target, + Init::step_build_wasm, + Init::step_create_dir, + Init::step_create_json, + Init::step_copy_readme, + Init::step_install_wasm_bindgen, + Init::step_running_wasm_bindgen, + ] + }; + let mut step = Step::new(steps.len()); + + let started = Instant::now(); + + for s in steps { + s(self, &step, log)?; + step.inc(); + } - info!(&log, "Writing a package.json..."); - manifest::write_package_json(&crate_path, scope, disable_dts)?; - #[cfg(not(target_os = "windows"))] - info!( - &log, - "Wrote a package.json at {}/pkg/package.json.", &crate_path - ); - #[cfg(target_os = "windows")] - info!( - &log, - "Wrote a package.json at {}\\pkg\\package.json.", &crate_path - ); + let duration = HumanDuration(started.elapsed()); + info!(&log, "Done in {}.", &duration); + info!( + &log, + "Your WASM pkg is ready to publish at {}/pkg.", &self.crate_path + ); + + PBAR.message(&format!("{} Done in {}", emoji::SPARKLE, &duration)); + + PBAR.message(&format!( + "{} Your WASM pkg is ready to publish at {}/pkg.", + emoji::PACKAGE, + &self.crate_path + )); + Ok(()) + } - info!(&log, "Copying readme from crate..."); - readme::copy_from_crate(&crate_path)?; - #[cfg(not(target_os = "windows"))] - info!(&log, "Copied readme from crate to {}/pkg.", &crate_path); - #[cfg(target_os = "windows")] - info!(&log, "Copied readme from crate to {}\\pkg.", &crate_path); + fn step_add_wasm_target(&mut self, step: &Step, log: &Logger) -> result::Result<(), Error> { + info!(&log, "Adding wasm-target..."); + build::rustup_add_wasm_target(step)?; + info!(&log, "Adding wasm-target was successful."); + Ok(()) + } - info!(&log, "Installing wasm-bindgen-cli..."); - bindgen::cargo_install_wasm_bindgen()?; - info!(&log, "Installing wasm-bindgen-cli was successful."); + fn step_build_wasm(&mut self, step: &Step, log: &Logger) -> result::Result<(), Error> { + info!(&log, "Building wasm..."); + build::cargo_build_wasm(&self.crate_path, step)?; + + #[cfg(not(target_os = "windows"))] + info!( + &log, + "wasm built at {}/target/wasm32-unknown-unknown/release.", &self.crate_path + ); + #[cfg(target_os = "windows")] + info!( + &log, + "wasm built at {}\\target\\wasm32-unknown-unknown\\release.", &self.crate_path + ); + Ok(()) + } - info!(&log, "Getting the crate name from the manifest..."); - let name = manifest::get_crate_name(&crate_path)?; - #[cfg(not(target_os = "windows"))] - info!( - &log, - "Got crate name {} from the manifest at {}/Cargo.toml.", &name, &crate_path - ); - #[cfg(target_os = "windows")] - info!( - &log, - "Got crate name {} from the manifest at {}\\Cargo.toml.", &name, &crate_path - ); + fn step_create_dir(&mut self, step: &Step, log: &Logger) -> result::Result<(), Error> { + info!(&log, "Creating a pkg directory..."); + create_pkg_dir(&self.crate_path, step)?; + info!(&log, "Created a pkg directory at {}.", &self.crate_path); + Ok(()) + } - info!(&log, "Building the wasm bindings..."); - bindgen::wasm_bindgen_build(&crate_path, &name, disable_dts, target)?; - #[cfg(not(target_os = "windows"))] - info!(&log, "wasm bindings were built at {}/pkg.", &crate_path); - #[cfg(target_os = "windows")] - info!(&log, "wasm bindings were built at {}\\pkg.", &crate_path); + fn step_create_json(&mut self, step: &Step, log: &Logger) -> result::Result<(), Error> { + info!(&log, "Writing a package.json..."); + manifest::write_package_json(&self.crate_path, &self.scope, self.disable_dts, step)?; + #[cfg(not(target_os = "windows"))] + info!( + &log, + "Wrote a package.json at {}/pkg/package.json.", &self.crate_path + ); + #[cfg(target_os = "windows")] + info!( + &log, + "Wrote a package.json at {}\\pkg\\package.json.", &self.crate_path + ); + Ok(()) + } - let duration = HumanDuration(started.elapsed()); - info!(&log, "Done in {}.", &duration); - info!( - &log, - "Your WASM pkg is ready to publish at {}/pkg.", &crate_path - ); + fn step_copy_readme(&mut self, step: &Step, log: &Logger) -> result::Result<(), Error> { + info!(&log, "Copying readme from crate..."); + readme::copy_from_crate(&self.crate_path, step)?; + #[cfg(not(target_os = "windows"))] + info!( + &log, + "Copied readme from crate to {}/pkg.", &self.crate_path + ); + #[cfg(target_os = "windows")] + info!( + &log, + "Copied readme from crate to {}\\pkg.", &self.crate_path + ); + Ok(()) + } - PBAR.message(&format!("{} Done in {}", emoji::SPARKLE, &duration)); + fn step_install_wasm_bindgen( + &mut self, + step: &Step, + log: &Logger, + ) -> result::Result<(), Error> { + info!(&log, "Installing wasm-bindgen-cli..."); + bindgen::cargo_install_wasm_bindgen(step)?; + info!(&log, "Installing wasm-bindgen-cli was successful."); + + info!(&log, "Getting the crate name from the manifest..."); + self.crate_name = Some(manifest::get_crate_name(&self.crate_path)?); + #[cfg(not(target_os = "windows"))] + info!( + &log, + "Got crate name {} from the manifest at {}/Cargo.toml.", + &self.crate_name.as_ref().unwrap(), + &self.crate_path + ); + #[cfg(target_os = "windows")] + info!( + &log, + "Got crate name {} from the manifest at {}\\Cargo.toml.", + &self.crate_name.as_ref().unwrap(), + &self.crate_path + ); + Ok(()) + } - PBAR.message(&format!( - "{} Your WASM pkg is ready to publish at {}/pkg.", - emoji::PACKAGE, - &crate_path - )); - Ok(()) + fn step_running_wasm_bindgen( + &mut self, + step: &Step, + log: &Logger, + ) -> result::Result<(), Error> { + info!(&log, "Building the wasm bindings..."); + bindgen::wasm_bindgen_build( + &self.crate_path, + &self.crate_name.as_ref().unwrap(), + self.disable_dts, + &self.target, + step, + )?; + #[cfg(not(target_os = "windows"))] + info!( + &log, + "wasm bindings were built at {}/pkg.", &self.crate_path + ); + #[cfg(target_os = "windows")] + info!( + &log, + "wasm bindings were built at {}\\pkg.", &self.crate_path + ); + Ok(()) + } } fn pack(path: Option, log: &Logger) -> result::Result<(), Error> { diff --git a/src/manifest.rs b/src/manifest.rs index 8662eeaaa..09b4700bc 100644 --- a/src/manifest.rs +++ b/src/manifest.rs @@ -1,9 +1,9 @@ use std::fs::File; use std::io::prelude::*; -use console::style; use emoji; use error::Error; +use progressbar::Step; use serde_json; use toml; use PBAR; @@ -53,7 +53,7 @@ fn read_cargo_toml(path: &str) -> Result { } impl CargoManifest { - fn into_npm(mut self, scope: Option, disable_dts: bool) -> NpmPackage { + fn into_npm(mut self, scope: &Option, disable_dts: bool) -> NpmPackage { let filename = self.package.name.replace("-", "_"); let wasm_file = format!("{}_bg.wasm", filename); let js_file = format!("{}.js", filename); @@ -95,14 +95,11 @@ impl CargoManifest { /// Generate a package.json file inside in `./pkg`. pub fn write_package_json( path: &str, - scope: Option, + scope: &Option, disable_dts: bool, + step: &Step, ) -> Result<(), Error> { - let step = format!( - "{} {}Writing a package.json...", - style("[4/7]").bold().dim(), - emoji::MEMO - ); + let msg = format!("{}Writing a package.json...", emoji::MEMO); let warn_fmt = |field| { format!( @@ -111,7 +108,7 @@ pub fn write_package_json( ) }; - let pb = PBAR.message(&step); + let pb = PBAR.step(step, &msg); let pkg_file_path = format!("{}/pkg/package.json", path); let mut pkg_file = File::create(pkg_file_path)?; let crate_data = read_cargo_toml(path)?; diff --git a/src/progressbar.rs b/src/progressbar.rs index a5a6e6e23..a02a548be 100644 --- a/src/progressbar.rs +++ b/src/progressbar.rs @@ -2,6 +2,7 @@ use console::style; use emoji; use error::Error; use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; +use std::fmt; pub struct ProgressOutput { bar: MultiProgress, @@ -14,6 +15,11 @@ impl ProgressOutput { } } + pub fn step(&self, step: &Step, message: &str) -> ProgressBar { + let msg = format!("{} {}", style(step).bold().dim(), message); + self.bar.add(Self::progressbar(&msg)) + } + pub fn message(&self, message: &str) -> ProgressBar { self.bar.add(Self::progressbar(message)) } @@ -67,3 +73,23 @@ impl ProgressOutput { self.bar.join_and_clear().map_err(|e| Error::from(e)) } } + +pub struct Step { + current: usize, + total: usize, +} + +impl Step { + pub fn new(total: usize) -> Step { + Step { current: 1, total } + } + pub fn inc(&mut self) { + self.current += 1; + } +} + +impl fmt::Display for Step { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "[{}/{}]", self.current, self.total) + } +} diff --git a/src/readme.rs b/src/readme.rs index 7178cbab7..7e0cae262 100644 --- a/src/readme.rs +++ b/src/readme.rs @@ -1,17 +1,13 @@ -use console::style; use error::Error; use std::fs; use emoji; +use progressbar::Step; use PBAR; -pub fn copy_from_crate(path: &str) -> Result<(), Error> { - let step = format!( - "{} {}Copying over your README...", - style("[5/7]").bold().dim(), - emoji::DANCERS - ); - let pb = PBAR.message(&step); +pub fn copy_from_crate(path: &str, step: &Step) -> Result<(), Error> { + let msg = format!("{}Copying over your README...", emoji::DANCERS); + let pb = PBAR.step(step, &msg); let crate_readme_path = format!("{}/README.md", path); let new_readme_path = format!("{}/pkg/README.md", path); if let Err(_) = fs::copy(&crate_readme_path, &new_readme_path) { diff --git a/tests/manifest/main.rs b/tests/manifest/main.rs index 995273a73..79940200c 100644 --- a/tests/manifest/main.rs +++ b/tests/manifest/main.rs @@ -27,9 +27,10 @@ fn it_gets_the_crate_name_provided_path() { #[test] fn it_creates_a_package_json_default_path() { + let step = wasm_pack::progressbar::Step::new(1); let path = ".".to_string(); - wasm_pack::command::create_pkg_dir(&path).unwrap(); - assert!(manifest::write_package_json(&path, None, false).is_ok()); + wasm_pack::command::create_pkg_dir(&path, &step).unwrap(); + assert!(manifest::write_package_json(&path, &None, false, &step).is_ok()); let package_json_path = format!("{}/pkg/package.json", &path); assert!(fs::metadata(package_json_path).is_ok()); assert!(utils::read_package_json(&path).is_ok()); @@ -48,9 +49,10 @@ fn it_creates_a_package_json_default_path() { #[test] fn it_creates_a_package_json_provided_path() { + let step = wasm_pack::progressbar::Step::new(1); let path = "tests/fixtures/js-hello-world".to_string(); - wasm_pack::command::create_pkg_dir(&path).unwrap(); - assert!(manifest::write_package_json(&path, None, false).is_ok()); + wasm_pack::command::create_pkg_dir(&path, &step).unwrap(); + assert!(manifest::write_package_json(&path, &None, false, &step).is_ok()); let package_json_path = format!("{}/pkg/package.json", &path); assert!(fs::metadata(package_json_path).is_ok()); assert!(utils::read_package_json(&path).is_ok()); @@ -60,9 +62,10 @@ fn it_creates_a_package_json_provided_path() { #[test] fn it_creates_a_package_json_provided_path_with_scope() { + let step = wasm_pack::progressbar::Step::new(1); let path = "tests/fixtures/scopes".to_string(); - wasm_pack::command::create_pkg_dir(&path).unwrap(); - assert!(manifest::write_package_json(&path, Some("test".to_string()), false).is_ok()); + wasm_pack::command::create_pkg_dir(&path, &step).unwrap(); + assert!(manifest::write_package_json(&path, &Some("test".to_string()), false, &step).is_ok()); let package_json_path = format!("{}/pkg/package.json", &path); assert!(fs::metadata(package_json_path).is_ok()); assert!(utils::read_package_json(&path).is_ok()); diff --git a/tests/readme/main.rs b/tests/readme/main.rs index 6ab324f6a..65d59da4c 100644 --- a/tests/readme/main.rs +++ b/tests/readme/main.rs @@ -9,8 +9,9 @@ use wasm_pack::readme; #[test] fn it_copies_a_readme_default_path() { + let step = wasm_pack::progressbar::Step::new(1); let path = ".".to_string(); - assert!(readme::copy_from_crate(&path).is_ok()); + assert!(readme::copy_from_crate(&path, &step).is_ok()); let crate_readme_path = format!("{}/README.md", &path); let pkg_readme_path = format!("{}/pkg/README.md", &path); assert!(fs::metadata(&pkg_readme_path).is_ok()); @@ -21,8 +22,9 @@ fn it_copies_a_readme_default_path() { #[test] fn it_creates_a_package_json_provided_path() { + let step = wasm_pack::progressbar::Step::new(1); let path = "tests/fixtures/js-hello-world".to_string(); - assert!(readme::copy_from_crate(&path).is_ok()); + assert!(readme::copy_from_crate(&path, &step).is_ok()); let crate_readme_path = format!("{}/README.md", &path); let pkg_readme_path = format!("{}/pkg/README.md", &path); assert!(fs::metadata(&pkg_readme_path).is_ok());