Repository: ashleygwilliams/wasm-pack
Pull request #78 (2018-04-06 13:48:28)

Refactor main.rs
This pull request is designed to move all the functionality out of the main.rs binary and into the main library itself - for testability and to hopefully provide some help with https://github.com/ashleygwilliams/wasm-pack/issues/25 .

Currently throws warning due to line 11 in command.rs - unused import of quicli - import is used for the StructOpt derive macro, so is needed to be imported, but due to no structs/functions from quicli being usied it still throws this warning.


Patch:
diff --git a/src/command.rs b/src/command.rs
new file mode 100644
index 0000000..0462520
--- /dev/null
+++ b/src/command.rs
@@ -0,0 +1,99 @@
+use PBAR;
+use bindgen;
+use build;
+use console::style;
+use emoji;
+use failure::Error;
+use indicatif::HumanDuration;
+use manifest;
+use npm;
+use quicli::prelude::*;
+use readme;
+use std::fs;
+use std::result;
+use std::time::Instant;
+
+#[derive(Debug, StructOpt)]
+pub enum Command {
+    #[structopt(name = "init")]
+    /// 🐣  initialize a package.json based on your cmpiled wasm
+    Init {
+        path: Option<String>,
+        #[structopt(long = "scope", short = "s")]
+        scope: Option<String>,
+    },
+    #[structopt(name = "pack")]
+    /// 🍱  create a tar of your npm package but don't ublish! [NOT IMPLEMENTED]
+    Pack { path: Option<String> },
+    #[structopt(name = "publish")]
+    /// 🎆  pack up your npm package and publish! [NOT MPLEMENTED]
+    Publish { path: Option<String> },
+}
+
+// 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);
+    let pkg_dir_path = format!("{}/pkg", path);
+    fs::create_dir_all(pkg_dir_path)?;
+    pb.finish();
+    Ok(())
+}
+
+pub fn init_command(path: Option<String>, scope: Option<String>) -> result::Result<(), Error> {
+    let started = Instant::now();
+
+    let crate_path = set_crate_path(path);
+
+    build::rustup_add_wasm_target();
+    build::cargo_build_wasm(&crate_path);
+    create_pkg_dir(&crate_path)?;
+    manifest::write_package_json(&crate_path, scope)?;
+    readme::copy_from_crate(&crate_path)?;
+    bindgen::cargo_install_wasm_bindgen();
+    let name = manifest::get_crate_name(&crate_path)?;
+    bindgen::wasm_bindgen_build(&crate_path, &name);
+    PBAR.one_off_message(&format!(
+        "{} Done in {}",
+        emoji::SPARKLE,
+        HumanDuration(started.elapsed())
+    ));
+    PBAR.one_off_message(&format!(
+        "{} Your WASM pkg is ready to publish at {}/pkg",
+        emoji::PACKAGE,
+        &crate_path
+    ));
+    PBAR.done()?;
+    Ok(())
+}
+
+pub fn pack_command(path: Option<String>) -> result::Result<(), Error> {
+    let crate_path = set_crate_path(path);
+
+    npm::npm_pack(&crate_path);
+    println!("🎒  packed up your package!");
+    Ok(())
+}
+
+pub fn publish_command(path: Option<String>) -> result::Result<(), Error> {
+    let crate_path = set_crate_path(path);
+
+    npm::npm_publish(&crate_path);
+    println!("💥  published your package!");
+    Ok(())
+}
+
+fn set_crate_path(path: Option<String>) -> String {
+    let crate_path = match path {
+        Some(p) => p,
+        None => ".".to_string(),
+    };
+
+    crate_path
+}
diff --git a/src/lib.rs b/src/lib.rs
index 2330b02..46009a9 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -3,6 +3,7 @@ extern crate failure;
 extern crate indicatif;
 #[macro_use]
 extern crate lazy_static;
+extern crate quicli;
 #[macro_use]
 extern crate serde_derive;
 extern crate serde_json;
@@ -10,31 +11,26 @@ extern crate toml;
 
 pub mod bindgen;
 pub mod build;
+pub mod command;
 pub mod emoji;
 pub mod manifest;
 pub mod npm;
 pub mod progressbar;
 pub mod readme;
 
-use std::fs;
-
-use console::style;
-use failure::Error;
 use progressbar::ProgressOutput;
+use quicli::prelude::*;
 
 lazy_static! {
     pub static ref PBAR: ProgressOutput = { ProgressOutput::new() };
 }
 
-pub fn create_pkg_dir(path: &str) -> Result<(), Error> {
-    let step = format!(
-        "{} {}Creating a pkg directory...",
-        style("[3/7]").bold().dim(),
-        emoji::FOLDER
-    );
-    let pb = PBAR.message(&step);
-    let pkg_dir_path = format!("{}/pkg", path);
-    fs::create_dir_all(pkg_dir_path)?;
-    pb.finish();
-    Ok(())
+/// 📦 ✨  pack and publish your wasm!
+#[derive(Debug, StructOpt)]
+pub struct Cli {
+    #[structopt(subcommand)] // Note that we mark a field as a subcommand
+    pub cmd: command::Command,
+    ///  log all the things
+    #[structopt(long = "verbose", short = "v", parse(from_occurrences))]
+    pub verbosity: u8,
 }
diff --git a/src/main.rs b/src/main.rs
index bf56f92..afc7355 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -4,82 +4,18 @@ extern crate indicatif;
 #[macro_use]
 extern crate quicli;
 
-use std::time::Instant;
-
-use indicatif::HumanDuration;
 use quicli::prelude::*;
-use wasm_pack::{bindgen, build, emoji, manifest, npm, readme, PBAR};
-
-/// 📦 ✨  pack and publish your wasm!
-#[derive(Debug, StructOpt)]
-struct Cli {
-    #[structopt(subcommand)] // Note that we mark a field as a subcommand
-    cmd: Command,
-    /// 📝  log all the things!
-    #[structopt(long = "verbose", short = "v", parse(from_occurrences))]
-    verbosity: u8,
-}
-
-#[derive(Debug, StructOpt)]
-enum Command {
-    #[structopt(name = "init")]
-    /// 🐣  initialize a package.json based on your compiled wasm
-    Init {
-        path: Option<String>,
-        #[structopt(long = "scope", short = "s")]
-        scope: Option<String>,
-    },
-    #[structopt(name = "pack")]
-    /// 🍱  create a tar of your npm package but don't publish! [NOT IMPLEMENTED]
-    Pack { path: Option<String> },
-    #[structopt(name = "publish")]
-    /// 🎆  pack up your npm package and publish! [NOT IMPLEMENTED]
-    Publish { path: Option<String> },
-}
+use wasm_pack::Cli;
+use wasm_pack::command::{init_command, pack_command, publish_command, Command};
 
 main!(|args: Cli, log_level: verbosity| match args.cmd {
     Command::Init { path, scope } => {
-        let started = Instant::now();
-
-        let crate_path = match path {
-            Some(p) => p,
-            None => ".".to_string(),
-        };
-
-        build::rustup_add_wasm_target();
-        build::cargo_build_wasm(&crate_path);
-        wasm_pack::create_pkg_dir(&crate_path)?;
-        manifest::write_package_json(&crate_path, scope)?;
-        readme::copy_from_crate(&crate_path)?;
-        bindgen::cargo_install_wasm_bindgen();
-        let name = manifest::get_crate_name(&crate_path)?;
-        bindgen::wasm_bindgen_build(&crate_path, &name);
-        PBAR.one_off_message(&format!(
-            "{} Done in {}",
-            emoji::SPARKLE,
-            HumanDuration(started.elapsed())
-        ));
-        PBAR.one_off_message(&format!(
-            "{} Your WASM pkg is ready to publish at {}/pkg",
-            emoji::PACKAGE,
-            &crate_path
-        ));
-        PBAR.done()?;
+        init_command(path, scope)?;
     }
     Command::Pack { path } => {
-        let crate_path = match path {
-            Some(p) => p,
-            None => ".".to_string(),
-        };
-        npm::npm_pack(&crate_path);
-        println!("🎒  packed up your package!");
+        pack_command(path)?;
     }
     Command::Publish { path } => {
-        let crate_path = match path {
-            Some(p) => p,
-            None => ".".to_string(),
-        };
-        npm::npm_publish(&crate_path);
-        println!("💥  published your package!");
+        publish_command(path)?;
     }
 });


Test patch:
diff --git a/tests/manifest/main.rs b/tests/manifest/main.rs
index 22a2f16..2ef3a6a 100644
--- a/tests/manifest/main.rs
+++ b/tests/manifest/main.rs
@@ -28,7 +28,7 @@ fn it_gets_the_crate_name_provided_path() {
 #[test]
 fn it_creates_a_package_json_default_path() {
     let path = ".".to_string();
-    wasm_pack::create_pkg_dir(&path).unwrap();
+    wasm_pack::command::create_pkg_dir(&path).unwrap();
     assert!(manifest::write_package_json(&path, None).is_ok());
     let package_json_path = format!("{}/pkg/package.json", &path);
     assert!(fs::metadata(package_json_path).is_ok());
@@ -46,7 +46,7 @@ fn it_creates_a_package_json_default_path() {
 #[test]
 fn it_creates_a_package_json_provided_path() {
     let path = "tests/fixtures/js-hello-world".to_string();
-    wasm_pack::create_pkg_dir(&path).unwrap();
+    wasm_pack::command::create_pkg_dir(&path).unwrap();
     assert!(manifest::write_package_json(&path, None).is_ok());
     let package_json_path = format!("{}/pkg/package.json", &path);
     assert!(fs::metadata(package_json_path).is_ok());
@@ -59,7 +59,7 @@ fn it_creates_a_package_json_provided_path() {
 #[test]
 fn it_creates_a_package_json_provided_path_with_scope() {
     let path = "tests/fixtures/scopes".to_string();
-    wasm_pack::create_pkg_dir(&path).unwrap();
+    wasm_pack::command::create_pkg_dir(&path).unwrap();
     assert!(manifest::write_package_json(&path, Some("test".to_string())).is_ok());
     let package_json_path = format!("{}/pkg/package.json", &path);
     assert!(fs::metadata(package_json_path).is_ok());