Repository: rustwasm/wasm-pack (rust)

Issue:
use std::path::Path[Buf] and join for paths
```
$ cargo run -- init myproject/
    Finished dev [unoptimized + debuginfo] target(s) in 0.08s
     Running `target/debug/wasm-pack init myproject/`

  [1/8] Checking crate configuration...
  [2/8] Adding WASM target...
  [3/8] Compiling to WASM...
  [4/8] Creating a pkg directory...
  [5/8] Writing a package.json...
  :-) [WARN]: Field description is missing from Cargo.toml. It is not necessary, but recommended
  :-) [WARN]: Field repository is missing from Cargo.toml. It is not necessary, but recommended
  :-) [WARN]: Field license is missing from Cargo.toml. It is not necessary, but recommended
  [6/8] Copying over your README...
  :-) [WARN]: origin crate has no README
  [7/8] Installing WASM-bindgen...
  [8/8] Running WASM-bindgen...
  :-) Done in 2 minutes
| :-) Your WASM pkg is ready to publish at myproject//pkg.
```

In the last line it says "Your WASM pkg is ready to publish at myproject//pkg.". It should probably just be "myproject/pkg".

This is on Linux.

Pull request:
Use PathBuf instead of String to handle paths
I think this is it. I want to take another look tomorrow to validate that I didn't miss something.

Fixes #213 

Make sure these boxes are checked! 📦✅

- [x] You have the latest version of `rustfmt` installed and have your 
      cloned directory set to nightly
```bash
$ rustup override set nightly
$ rustup component add rustfmt-preview --toolchain nightly
```
- [x] You ran `rustfmt` on the code base before submitting
- [x] You reference which issue is being closed in the PR text

✨✨ 😄 Thanks so much for contributing to wasm-pack! 😄 ✨✨


Patch:
diff --git a/src/bindgen.rs b/src/bindgen.rs
index 61d9ac1..f464644 100644
--- a/src/bindgen.rs
+++ b/src/bindgen.rs
@@ -3,6 +3,7 @@
 use emoji;
 use error::Error;
 use progressbar::Step;
+use std::path::Path;
 use std::process::Command;
 use PBAR;
 
@@ -30,7 +31,7 @@ pub fn cargo_install_wasm_bindgen(step: &Step) -> Result<(), Error> {
 /// Run the `wasm-bindgen` CLI to generate bindings for the current crate's
 /// `.wasm`.
 pub fn wasm_bindgen_build(
-    path: &str,
+    path: &Path,
     name: &str,
     disable_dts: bool,
     target: &str,
diff --git a/src/build.rs b/src/build.rs
index 1744f99..c568d91 100644
--- a/src/build.rs
+++ b/src/build.rs
@@ -3,6 +3,7 @@
 use emoji;
 use error::Error;
 use progressbar::Step;
+use std::path::Path;
 use std::process::Command;
 use PBAR;
 
@@ -46,7 +47,7 @@ fn ensure_nightly() -> Result<(), Error> {
 
 /// Run `cargo build` with the `nightly` toolchain and targetting
 /// `wasm32-unknown-unknown`.
-pub fn cargo_build_wasm(path: &str, debug: bool, step: &Step) -> Result<(), Error> {
+pub fn cargo_build_wasm(path: &Path, debug: bool, step: &Step) -> Result<(), Error> {
     let msg = format!("{}Compiling to WASM...", emoji::CYCLONE);
     PBAR.step(step, &msg);
     let output = {
diff --git a/src/command/init.rs b/src/command/init.rs
index bec96f8..c405a80 100644
--- a/src/command/init.rs
+++ b/src/command/init.rs
@@ -11,14 +11,15 @@ use progressbar::Step;
 use readme;
 use slog::Logger;
 use std::fs;
+use std::path::{Path, PathBuf};
 use std::time::Instant;
 use PBAR;
 
 /// Construct our `pkg` directory in the crate.
-pub fn create_pkg_dir(path: &str, step: &Step) -> Result<(), Error> {
+pub fn create_pkg_dir(path: &Path, step: &Step) -> Result<(), Error> {
     let msg = format!("{}Creating a pkg directory...", emoji::FOLDER);
     PBAR.step(step, &msg);
-    let pkg_dir_path = format!("{}/pkg", path);
+    let pkg_dir_path = path.join("pkg");
     fs::create_dir_all(pkg_dir_path)?;
     Ok(())
 }
@@ -38,7 +39,7 @@ pub enum InitMode {
 
 /// Everything required to configure and run the `wasm-pack init` command.
 pub struct Init {
-    crate_path: String,
+    crate_path: PathBuf,
     scope: Option<String>,
     disable_dts: bool,
     target: String,
@@ -51,7 +52,7 @@ type InitStep = fn(&mut Init, &Step, &Logger) -> Result<(), Error>;
 impl Init {
     /// Construct a new `Init` command.
     pub fn new(
-        path: Option<String>,
+        path: Option<PathBuf>,
         scope: Option<String>,
         disable_dts: bool,
         target: String,
@@ -121,15 +122,16 @@ impl Init {
         info!(&log, "Done in {}.", &duration);
         info!(
             &log,
-            "Your WASM pkg is ready to publish at {}/pkg.", &self.crate_path
+            "Your WASM pkg is ready to publish at {:#?}.",
+            &self.crate_path.join("pkg")
         );
 
         PBAR.message(&format!("{} Done in {}", emoji::SPARKLE, &duration));
 
         PBAR.message(&format!(
-            "{} Your WASM pkg is ready to publish at {}/pkg.",
+            "{} Your WASM pkg is ready to publish at {:#?}.",
             emoji::PACKAGE,
-            &self.crate_path
+            &self.crate_path.join("pkg")
         ));
         Ok(())
     }
@@ -152,15 +154,14 @@ impl Init {
         info!(&log, "Building wasm...");
         build::cargo_build_wasm(&self.crate_path, self.debug, 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
+            "wasm built at {:#?}.",
+            &self
+                .crate_path
+                .join("target")
+                .join("wasm32-unknown-unknown")
+                .join("release")
         );
         Ok(())
     }
@@ -168,7 +169,7 @@ impl Init {
     fn step_create_dir(&mut self, step: &Step, log: &Logger) -> 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);
+        info!(&log, "Created a pkg directory at {:#?}.", &self.crate_path);
         Ok(())
     }
 
@@ -181,15 +182,10 @@ impl Init {
             &self.target,
             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
+            "Wrote a package.json at {:#?}.",
+            &self.crate_path.join("pkg").join("package.json")
         );
         Ok(())
     }
@@ -197,15 +193,10 @@ impl Init {
     fn step_copy_readme(&mut self, step: &Step, log: &Logger) -> 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
+            "Copied readme from crate to {:#?}.",
+            &self.crate_path.join("pkg")
         );
         Ok(())
     }
@@ -217,19 +208,11 @@ impl Init {
 
         info!(&log, "Getting the crate name from the manifest...");
         self.crate_name = 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,
-            &self.crate_path
-        );
-        #[cfg(target_os = "windows")]
         info!(
             &log,
-            "Got crate name {} from the manifest at {}\\Cargo.toml.",
+            "Got crate name {:#?} from the manifest at {:#?}.",
             &self.crate_name,
-            &self.crate_path
+            &self.crate_path.join("Cargo.toml")
         );
         Ok(())
     }
@@ -244,15 +227,10 @@ impl Init {
             self.debug,
             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
+            "wasm bindings were built at {:#?}.",
+            &self.crate_path.join("pkg")
         );
         Ok(())
     }
diff --git a/src/command/mod.rs b/src/command/mod.rs
index 2f477b9..2b9ed8d 100644
--- a/src/command/mod.rs
+++ b/src/command/mod.rs
@@ -12,6 +12,7 @@ use self::pack::pack;
 use self::publish::publish;
 use error::Error;
 use slog::Logger;
+use std::path::PathBuf;
 use std::result;
 use PBAR;
 
@@ -22,7 +23,8 @@ pub enum Command {
     /// 🐣  initialize a package.json based on your compiled wasm!
     Init {
         /// The path to the Rust crate.
-        path: Option<String>,
+        #[structopt(parse(from_os_str))]
+        path: Option<PathBuf>,
 
         /// The npm scope to use in package.json, if any.
         #[structopt(long = "scope", short = "s")]
@@ -49,15 +51,17 @@ pub enum Command {
     #[structopt(name = "pack")]
     /// 🍱  create a tar of your npm package but don't publish!
     Pack {
-        /// The path to the Rust crate.
-        path: Option<String>,
+        /// The path to the Rust crate.  
+        #[structopt(parse(from_os_str))]
+        path: Option<PathBuf>,
     },
 
     #[structopt(name = "publish")]
     /// 🎆  pack up your npm package and publish!
     Publish {
         /// The path to the Rust crate.
-        path: Option<String>,
+        #[structopt(parse(from_os_str))]
+        path: Option<PathBuf>,
     },
 
     #[structopt(name = "login", alias = "adduser", alias = "add-user")]
diff --git a/src/command/pack.rs b/src/command/pack.rs
index c9c9ffd..fe1ca5f 100644
--- a/src/command/pack.rs
+++ b/src/command/pack.rs
@@ -2,26 +2,28 @@ use command::utils::{find_pkg_directory, set_crate_path};
 use error::Error;
 use npm;
 use slog::Logger;
+use std::path::PathBuf;
 use std::result;
 use PBAR;
 
 /// Executes the 'npm pack' command on the 'pkg' directory
 /// which creates a tarball that can be published to the NPM registry
-pub fn pack(path: Option<String>, log: &Logger) -> result::Result<(), Error> {
+pub fn pack(path: Option<PathBuf>, log: &Logger) -> result::Result<(), Error> {
     let crate_path = set_crate_path(path);
 
     info!(&log, "Packing up the npm package...");
     let pkg_directory = find_pkg_directory(&crate_path).ok_or(Error::PkgNotFound {
         message: format!(
-            "Unable to find the pkg directory at path '{}', or in a child directory of '{}'",
+            "Unable to find the pkg directory at path {:#?}, or in a child directory of {:#?}",
             &crate_path, &crate_path
         ),
     })?;
     npm::npm_pack(&pkg_directory.to_string_lossy())?;
-    #[cfg(not(target_os = "windows"))]
-    info!(&log, "Your package is located at {}/pkg", &crate_path);
-    #[cfg(target_os = "windows")]
-    info!(&log, "Your package is located at {}\\pkg", &crate_path);
+    info!(
+        &log,
+        "Your package is located at {:#?}",
+        crate_path.join("pkg")
+    );
 
     PBAR.message("🎒  packed up your package!");
     Ok(())
diff --git a/src/command/publish.rs b/src/command/publish.rs
index 2fb295f..2d67365 100644
--- a/src/command/publish.rs
+++ b/src/command/publish.rs
@@ -2,19 +2,20 @@ use command::utils::{find_pkg_directory, set_crate_path};
 use error::Error;
 use npm;
 use slog::Logger;
+use std::path::PathBuf;
 use std::result;
 use PBAR;
 
 /// Creates a tarball from a 'pkg' directory
 /// and publishes it to the NPM registry
-pub fn publish(path: Option<String>, log: &Logger) -> result::Result<(), Error> {
+pub fn publish(path: Option<PathBuf>, log: &Logger) -> result::Result<(), Error> {
     let crate_path = set_crate_path(path);
 
     info!(&log, "Publishing the npm package...");
     info!(&log, "npm info located in the npm debug log");
     let pkg_directory = find_pkg_directory(&crate_path).ok_or(Error::PkgNotFound {
         message: format!(
-            "Unable to find the pkg directory at path '{}', or in a child directory of '{}'",
+            "Unable to find the pkg directory at path '{:#?}', or in a child directory of '{:#?}'",
             &crate_path, &crate_path
         ),
     })?;
diff --git a/src/command/utils.rs b/src/command/utils.rs
index 925f527..3e0fb70 100644
--- a/src/command/utils.rs
+++ b/src/command/utils.rs
@@ -4,10 +4,10 @@ use std::path::{Path, PathBuf};
 
 /// If an explicit path is given, then use it, otherwise assume the current
 /// directory is the crate path.
-pub fn set_crate_path(path: Option<String>) -> String {
+pub fn set_crate_path(path: Option<PathBuf>) -> PathBuf {
     let crate_path = match path {
         Some(p) => p,
-        None => ".".to_string(),
+        None => PathBuf::from("."),
     };
 
     crate_path
@@ -15,10 +15,9 @@ pub fn set_crate_path(path: Option<String>) -> String {
 
 /// Locates the pkg directory from a specific path
 /// Returns None if unable to find the 'pkg' directory
-pub fn find_pkg_directory(guess_path: &str) -> Option<PathBuf> {
-    let path = PathBuf::from(guess_path);
-    if is_pkg_directory(&path) {
-        return Some(path);
+pub fn find_pkg_directory(path: &Path) -> Option<PathBuf> {
+    if is_pkg_directory(path) {
+        return Some(path.to_owned());
     }
 
     path.read_dir().ok().and_then(|entries| {
diff --git a/src/manifest.rs b/src/manifest.rs
index a6628c6..36e69df 100644
--- a/src/manifest.rs
+++ b/src/manifest.rs
@@ -2,6 +2,7 @@
 
 use std::fs::File;
 use std::io::prelude::*;
+use std::path::Path;
 
 use console::style;
 use emoji;
@@ -60,8 +61,8 @@ struct Repository {
     url: String,
 }
 
-fn read_cargo_toml(path: &str) -> Result<CargoManifest, Error> {
-    let manifest_path = format!("{}/Cargo.toml", path);
+fn read_cargo_toml(path: &Path) -> Result<CargoManifest, Error> {
+    let manifest_path = path.join("Cargo.toml");
     let mut cargo_file = File::open(manifest_path)?;
     let mut cargo_contents = String::new();
     cargo_file.read_to_string(&mut cargo_contents)?;
@@ -125,7 +126,7 @@ impl CargoManifest {
 
 /// Generate a package.json file inside in `./pkg`.
 pub fn write_package_json(
-    path: &str,
+    path: &Path,
     scope: &Option<String>,
     disable_dts: bool,
     target: &str,
@@ -141,7 +142,7 @@ pub fn write_package_json(
     };
 
     PBAR.step(step, &msg);
-    let pkg_file_path = format!("{}/pkg/package.json", path);
+    let pkg_file_path = path.join("pkg").join("package.json");
     let mut pkg_file = File::create(pkg_file_path)?;
     let crate_data = read_cargo_toml(path)?;
     let npm_data = crate_data.into_npm(scope, disable_dts, target);
@@ -162,12 +163,12 @@ pub fn write_package_json(
 }
 
 /// Get the crate name for the crate at the given path.
-pub fn get_crate_name(path: &str) -> Result<String, Error> {
+pub fn get_crate_name(path: &Path) -> Result<String, Error> {
     Ok(read_cargo_toml(path)?.package.name)
 }
 
 /// Check that the crate the given path is properly configured.
-pub fn check_crate_config(path: &str, step: &Step) -> Result<(), Error> {
+pub fn check_crate_config(path: &Path, step: &Step) -> Result<(), Error> {
     let msg = format!("{}Checking crate configuration...", emoji::WRENCH);
     PBAR.step(&step, &msg);
     check_wasm_bindgen(path)?;
@@ -175,7 +176,7 @@ pub fn check_crate_config(path: &str, step: &Step) -> Result<(), Error> {
     Ok(())
 }
 
-fn check_wasm_bindgen(path: &str) -> Result<(), Error> {
+fn check_wasm_bindgen(path: &Path) -> Result<(), Error> {
     if read_cargo_toml(path)?.dependencies.map_or(false, |x| {
         !x.wasm_bindgen.unwrap_or("".to_string()).is_empty()
     }) {
@@ -187,7 +188,7 @@ fn check_wasm_bindgen(path: &str) -> Result<(), Error> {
     ))
 }
 
-fn check_crate_type(path: &str) -> Result<(), Error> {
+fn check_crate_type(path: &Path) -> Result<(), Error> {
     if read_cargo_toml(path)?.lib.map_or(false, |lib| {
         lib.crate_type
             .map_or(false, |types| types.iter().any(|s| s == "cdylib"))
diff --git a/src/readme.rs b/src/readme.rs
index 5f631e0..d59d496 100644
--- a/src/readme.rs
+++ b/src/readme.rs
@@ -2,17 +2,18 @@
 
 use error::Error;
 use std::fs;
+use std::path::Path;
 
 use emoji;
 use progressbar::Step;
 use PBAR;
 
 /// Copy the crate's README into the `pkg` directory.
-pub fn copy_from_crate(path: &str, step: &Step) -> Result<(), Error> {
+pub fn copy_from_crate(path: &Path, step: &Step) -> Result<(), Error> {
     let msg = format!("{}Copying over your README...", emoji::DANCERS);
     PBAR.step(step, &msg);
-    let crate_readme_path = format!("{}/README.md", path);
-    let new_readme_path = format!("{}/pkg/README.md", path);
+    let crate_readme_path = path.join("README.md");
+    let new_readme_path = path.join("pkg").join("README.md");
     if let Err(_) = fs::copy(&crate_readme_path, &new_readme_path) {
         PBAR.warn("origin crate has no README");
     };


Test patch:
diff --git a/tests/manifest/main.rs b/tests/manifest/main.rs
index cf66196..9594b8a 100644
--- a/tests/manifest/main.rs
+++ b/tests/manifest/main.rs
@@ -8,49 +8,55 @@ mod utils;
 
 use std::collections::HashSet;
 use std::fs;
+use std::path::PathBuf;
 
 use wasm_pack::manifest;
 
 #[test]
 fn it_gets_the_crate_name_default_path() {
-    assert!(manifest::get_crate_name(".").is_ok());
-    assert_eq!(manifest::get_crate_name(".").unwrap(), "wasm-pack");
+    let path = &PathBuf::from(".");
+    assert!(manifest::get_crate_name(path).is_ok());
+    assert_eq!(manifest::get_crate_name(path).unwrap(), "wasm-pack");
 }
 
 #[test]
 fn it_gets_the_crate_name_provided_path() {
-    assert!(manifest::get_crate_name("tests/fixtures/js-hello-world").is_ok());
-    assert_eq!(
-        manifest::get_crate_name("tests/fixtures/js-hello-world").unwrap(),
-        "js-hello-world"
-    );
+    let path = &PathBuf::from("tests/fixtures/js-hello-world");
+    assert!(manifest::get_crate_name(path).is_ok());
+    assert_eq!(manifest::get_crate_name(path).unwrap(), "js-hello-world");
 }
 
 #[test]
 fn it_checks_has_cdylib_default_path() {
     let step = wasm_pack::progressbar::Step::new(1);
-    assert!(manifest::check_crate_config(".", &step).is_err());
+    assert!(manifest::check_crate_config(&PathBuf::from("."), &step).is_err());
 }
 
 #[test]
 fn it_checks_has_cdylib_provided_path() {
     let step = wasm_pack::progressbar::Step::new(1);
-    assert!(manifest::check_crate_config("tests/fixtures/js-hello-world", &step).is_ok());
+    assert!(
+        manifest::check_crate_config(&PathBuf::from("tests/fixtures/js-hello-world"), &step)
+            .is_ok()
+    );
 }
 
 #[test]
 fn it_checks_has_cdylib_wrong_crate_type() {
     let step = wasm_pack::progressbar::Step::new(1);
-    assert!(manifest::check_crate_config("tests/fixtures/bad-cargo-toml", &step).is_err());
+    assert!(
+        manifest::check_crate_config(&PathBuf::from("tests/fixtures/bad-cargo-toml"), &step)
+            .is_err()
+    );
 }
 
 #[test]
 fn it_creates_a_package_json_default_path() {
     let step = wasm_pack::progressbar::Step::new(1);
-    let path = ".".to_string();
+    let path = PathBuf::from(".");
     wasm_pack::command::init::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);
+    let package_json_path = &path.join("pkg").join("package.json");
     assert!(fs::metadata(package_json_path).is_ok());
     assert!(utils::read_package_json(&path).is_ok());
     let pkg = utils::read_package_json(&path).unwrap();
@@ -75,10 +81,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();
+    let path = PathBuf::from("tests/fixtures/js-hello-world");
     wasm_pack::command::init::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);
+    let package_json_path = &path.join("pkg").join("package.json");
     assert!(fs::metadata(package_json_path).is_ok());
     assert!(utils::read_package_json(&path).is_ok());
     let pkg = utils::read_package_json(&path).unwrap();
@@ -96,12 +102,12 @@ 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();
+    let path = PathBuf::from("tests/fixtures/scopes");
     wasm_pack::command::init::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);
+    let package_json_path = &path.join("pkg").join("package.json");
     assert!(fs::metadata(package_json_path).is_ok());
     assert!(utils::read_package_json(&path).is_ok());
     let pkg = utils::read_package_json(&path).unwrap();
@@ -119,10 +125,10 @@ fn it_creates_a_package_json_provided_path_with_scope() {
 #[test]
 fn it_creates_a_pkg_json_with_correct_files_on_node() {
     let step = wasm_pack::progressbar::Step::new(1);
-    let path = ".".to_string();
+    let path = PathBuf::from(".");
     wasm_pack::command::init::create_pkg_dir(&path, &step).unwrap();
     assert!(manifest::write_package_json(&path, &None, false, "nodejs", &step).is_ok());
-    let package_json_path = format!("{}/pkg/package.json", &path);
+    let package_json_path = &path.join("pkg").join("package.json");
     assert!(fs::metadata(package_json_path).is_ok());
     assert!(utils::read_package_json(&path).is_ok());
     let pkg = utils::read_package_json(&path).unwrap();
@@ -148,10 +154,10 @@ fn it_creates_a_pkg_json_with_correct_files_on_node() {
 #[test]
 fn it_creates_a_package_json_with_correct_keys_when_types_are_skipped() {
     let step = wasm_pack::progressbar::Step::new(1);
-    let path = ".".to_string();
+    let path = PathBuf::from(".");
     wasm_pack::command::init::create_pkg_dir(&path, &step).unwrap();
     assert!(manifest::write_package_json(&path, &None, true, "", &step).is_ok());
-    let package_json_path = format!("{}/pkg/package.json", &path);
+    let package_json_path = &path.join("pkg").join("package.json");
     assert!(fs::metadata(package_json_path).is_ok());
     assert!(utils::read_package_json(&path).is_ok());
     let pkg = utils::read_package_json(&path).unwrap();
@@ -174,11 +180,15 @@ fn it_creates_a_package_json_with_correct_keys_when_types_are_skipped() {
 #[test]
 fn it_errors_when_wasm_bindgen_is_not_declared() {
     let step = wasm_pack::progressbar::Step::new(1);
-    assert!(manifest::check_crate_config("tests/fixtures/bad-cargo-toml", &step).is_err());
+    assert!(
+        manifest::check_crate_config(&PathBuf::from("tests/fixtures/bad-cargo-toml"), &step)
+            .is_err()
+    );
 }
 
 #[test]
 fn it_does_not_error_when_wasm_bindgen_is_declared() {
     let step = wasm_pack::progressbar::Step::new(1);
-    assert!(manifest::check_crate_config("tests/fixtures/js-hello-world", &step).is_ok());
+    let path = PathBuf::from("tests/fixtures/js-hello-world");
+    assert!(manifest::check_crate_config(&path, &step).is_ok());
 }
diff --git a/tests/manifest/utils.rs b/tests/manifest/utils.rs
index 25add46..cc3d609 100644
--- a/tests/manifest/utils.rs
+++ b/tests/manifest/utils.rs
@@ -1,5 +1,6 @@
 use std::fs::File;
 use std::io::prelude::*;
+use std::path::Path;
 
 use failure::Error;
 use serde_json;
@@ -23,8 +24,8 @@ pub struct Repository {
     pub url: String,
 }
 
-pub fn read_package_json(path: &str) -> Result<NpmPackage, Error> {
-    let manifest_path = format!("{}/pkg/package.json", path);
+pub fn read_package_json(path: &Path) -> Result<NpmPackage, Error> {
+    let manifest_path = path.join("pkg").join("package.json");
     let mut pkg_file = File::open(manifest_path)?;
     let mut pkg_contents = String::new();
     pkg_file.read_to_string(&mut pkg_contents)?;
diff --git a/tests/readme/main.rs b/tests/readme/main.rs
index 65d59da..337a70f 100644
--- a/tests/readme/main.rs
+++ b/tests/readme/main.rs
@@ -4,16 +4,17 @@ extern crate wasm_pack;
 mod utils;
 
 use std::fs;
+use std::path::PathBuf;
 
 use wasm_pack::readme;
 
 #[test]
 fn it_copies_a_readme_default_path() {
     let step = wasm_pack::progressbar::Step::new(1);
-    let path = ".".to_string();
+    let path = PathBuf::from(".");
     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);
+    let crate_readme_path = &path.join("README.md");
+    let pkg_readme_path = &path.join("pkg").join("README.md");
     assert!(fs::metadata(&pkg_readme_path).is_ok());
     let crate_readme = utils::read_file(&crate_readme_path).unwrap();
     let pkg_readme = utils::read_file(&pkg_readme_path).unwrap();
@@ -23,10 +24,10 @@ 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();
+    let path = PathBuf::from("tests/fixtures/js-hello-world");
     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);
+    let crate_readme_path = &path.join("README.md");
+    let pkg_readme_path = &path.join("pkg").join("README.md");
     assert!(fs::metadata(&pkg_readme_path).is_ok());
     let crate_readme = utils::read_file(&crate_readme_path).unwrap();
     let pkg_readme = utils::read_file(&pkg_readme_path).unwrap();
diff --git a/tests/readme/utils.rs b/tests/readme/utils.rs
index 64f8519..c5e2bbf 100644
--- a/tests/readme/utils.rs
+++ b/tests/readme/utils.rs
@@ -1,9 +1,9 @@
+use failure::Error;
 use std::fs::File;
 use std::io::Read;
+use std::path::Path;
 
-use failure::Error;
-
-pub fn read_file(path: &str) -> Result<String, Error> {
+pub fn read_file(path: &Path) -> Result<String, Error> {
     let mut file = File::open(path)?;
     let mut contents = String::new();
     file.read_to_string(&mut contents)?;