From 69b34d0529ac7c90dfcb4af49bf303104002f616 Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Sat, 9 Nov 2019 15:35:19 -0700 Subject: [PATCH 1/5] add first-class support for binary crates --- src/bindgen.rs | 75 +++++++++++----------- src/build/mod.rs | 2 +- src/manifest/mod.rs | 31 +++++++--- tests/all/build.rs | 40 ++++++++++++ tests/all/manifest.rs | 7 +++ tests/all/utils/fixture.rs | 124 ++++++++++++++++++++++++++++++++++++- 6 files changed, 234 insertions(+), 45 deletions(-) diff --git a/src/bindgen.rs b/src/bindgen.rs index 13da5904..eea7e504 100644 --- a/src/bindgen.rs +++ b/src/bindgen.rs @@ -28,49 +28,52 @@ pub fn wasm_bindgen_build( let out_dir = out_dir.to_str().unwrap(); - let wasm_path = data - .target_directory() - .join("wasm32-unknown-unknown") - .join(release_or_debug) - .join(data.crate_name()) - .with_extension("wasm"); + for target_name in data.targets() { + let wasm_path = data + .target_directory() + .join("wasm32-unknown-unknown") + .join(release_or_debug) + .join(target_name) + .with_extension("wasm"); - let dts_arg = if disable_dts { - "--no-typescript" - } else { - "--typescript" - }; - let bindgen_path = bindgen.binary("wasm-bindgen")?; + let dts_arg = if disable_dts { + "--no-typescript" + } else { + "--typescript" + }; + let bindgen_path = bindgen.binary("wasm-bindgen")?; - let mut cmd = Command::new(&bindgen_path); - cmd.arg(&wasm_path) - .arg("--out-dir") - .arg(out_dir) - .arg(dts_arg); + let mut cmd = Command::new(&bindgen_path); + cmd.arg(&wasm_path) + .arg("--out-dir") + .arg(out_dir) + .arg(dts_arg); - let target_arg = build_target_arg(target, &bindgen_path)?; - if supports_dash_dash_target(&bindgen_path)? { - cmd.arg("--target").arg(target_arg); - } else { - cmd.arg(target_arg); - } + let target_arg = build_target_arg(target, &bindgen_path)?; + if supports_dash_dash_target(&bindgen_path)? { + cmd.arg("--target").arg(target_arg); + } else { + cmd.arg(target_arg); + } - if let Some(value) = out_name { - cmd.arg("--out-name").arg(value); - } + if let Some(value) = out_name { + cmd.arg("--out-name").arg(value); + } - let profile = data.configured_profile(profile); - if profile.wasm_bindgen_debug_js_glue() { - cmd.arg("--debug"); - } - if !profile.wasm_bindgen_demangle_name_section() { - cmd.arg("--no-demangle"); - } - if profile.wasm_bindgen_dwarf_debug_info() { - cmd.arg("--keep-debug"); + let profile = data.configured_profile(profile); + if profile.wasm_bindgen_debug_js_glue() { + cmd.arg("--debug"); + } + if !profile.wasm_bindgen_demangle_name_section() { + cmd.arg("--no-demangle"); + } + if profile.wasm_bindgen_dwarf_debug_info() { + cmd.arg("--keep-debug"); + } + + child::run(cmd, "wasm-bindgen").context("Running the wasm-bindgen CLI")?; } - child::run(cmd, "wasm-bindgen").context("Running the wasm-bindgen CLI")?; Ok(()) } diff --git a/src/build/mod.rs b/src/build/mod.rs index 6a97035b..d9fd6220 100644 --- a/src/build/mod.rs +++ b/src/build/mod.rs @@ -81,7 +81,7 @@ pub fn cargo_build_wasm( let msg = format!("{}Compiling to Wasm...", emoji::CYCLONE); PBAR.info(&msg); let mut cmd = Command::new("cargo"); - cmd.current_dir(path).arg("build").arg("--lib"); + cmd.current_dir(path).arg("build"); match profile { BuildProfile::Profiling => { // Once there are DWARF debug info consumers, force enable debug diff --git a/src/manifest/mod.rs b/src/manifest/mod.rs index 0caaf420..8fc0166c 100644 --- a/src/manifest/mod.rs +++ b/src/manifest/mod.rs @@ -493,18 +493,24 @@ impl CrateData { Ok(()) } - fn check_crate_type(&self) -> Result<(), Error> { + fn valid_targets(&self) -> impl Iterator { + fn valid_kind(x: &str) -> bool { + x == "cdylib" || x == "bin" + } let pkg = &self.data.packages[self.current_idx]; - let any_cdylib = pkg - .targets + pkg.targets .iter() - .filter(|target| target.kind.iter().any(|k| k == "cdylib")) - .any(|target| target.crate_types.iter().any(|s| s == "cdylib")); - if any_cdylib { + .filter(|target| target.kind.iter().any(|k| valid_kind(k))) + .filter(|target| target.crate_types.iter().any(|s| valid_kind(s))) + } + + fn check_crate_type(&self) -> Result<(), Error> { + let any_valid = self.valid_targets().count() > 0; + if any_valid { return Ok(()); } bail!( - "crate-type must be cdylib to compile to wasm32-unknown-unknown. Add the following to your \ + "library crate-type must be cdylib to compile to wasm32-unknown-unknown. Add the following to your \ Cargo.toml file:\n\n\ [lib]\n\ crate-type = [\"cdylib\", \"rlib\"]" @@ -524,6 +530,17 @@ impl CrateData { } } + /// Get the target names that will be built for the current crate. + pub fn targets(&self) -> impl Iterator + '_ { + self.valid_targets().map(|x| { + if x.kind.iter().any(|x| x.ends_with("lib")) { + x.name.replace("-", "_") + } else { + x.name.clone() + } + }) + } + /// Get the prefix for output file names pub fn name_prefix(&self) -> String { match &self.out_name { diff --git a/tests/all/build.rs b/tests/all/build.rs index 98581aef..e32ec7f1 100644 --- a/tests/all/build.rs +++ b/tests/all/build.rs @@ -295,3 +295,43 @@ fn build_force() { .assert() .success(); } + +#[test] +fn bin_crate_behavior_identical() { + let fixture = utils::fixture::bin_crate(); + fixture.install_local_wasm_bindgen(); + fixture + .wasm_pack() + .arg("build") + .arg("--target") + .arg("nodejs") + .assert() + .success(); + let native_output = fixture.command("cargo").arg("run").output().unwrap(); + assert!(native_output.status.success()); + assert_eq!(native_output.stdout, b"Hello, World\n"); + let wasm_output = fixture.command("node").arg("pkg/foo.js").output().unwrap(); + assert!(wasm_output.status.success()); + assert_eq!(wasm_output.stdout, b"Hello, World\n"); +} + +#[test] +fn multi_bin_crate_procs_all() { + let fixture = utils::fixture::multi_bin_crate(); + fixture.install_local_wasm_bindgen(); + fixture + .wasm_pack() + .arg("build") + .arg("--target") + .arg("nodejs") + .assert() + .success(); + let pkg_path = |x: &str| { + let mut path = fixture.path.clone(); + path.push("pkg"); + path.push(x); + path + }; + assert!(pkg_path("foo.js").exists()); + assert!(pkg_path("sample.js").exists()); +} diff --git a/tests/all/manifest.rs b/tests/all/manifest.rs index 1f202a20..1a46c71a 100644 --- a/tests/all/manifest.rs +++ b/tests/all/manifest.rs @@ -63,6 +63,13 @@ fn it_checks_has_cdylib_wrong_crate_type() { assert!(crate_data.check_crate_config().is_err()); } +#[test] +fn it_accepts_binary_crates_without_cdylib() { + let fixture = fixture::bin_crate(); + let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); + crate_data.check_crate_config().unwrap(); +} + #[test] fn it_recognizes_a_map_during_depcheck() { let fixture = fixture::serde_feature(); diff --git a/tests/all/utils/fixture.rs b/tests/all/utils/fixture.rs index e076fc01..9e0d4c47 100644 --- a/tests/all/utils/fixture.rs +++ b/tests/all/utils/fixture.rs @@ -1,5 +1,6 @@ use binary_install::Cache; use std::env; +use std::ffi::OsStr; use std::fs; use std::mem::ManuallyDrop; use std::path::{Path, PathBuf}; @@ -210,6 +211,41 @@ impl Fixture { ) } + /// Add a `src/main.rs` file that contains a "hello world" program. + pub fn hello_world_src_main(&self) -> &Self { + self.file( + "src/main.rs", + r#" + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + + // Import the `console.log` function from the Web. + #[wasm_bindgen] + extern { + #[wasm_bindgen(js_namespace = console, js_name = log)] + fn console_log(s: &str); + } + + // On wasm, print() should forward to console.log. + #[cfg(target_arch = "wasm32")] + fn print(text: &str) { + console_log(text); + } + + // On not-wasm, print() should forward to println!(). + #[cfg(not(target_arch = "wasm32"))] + fn print(text: &str) { + println!("{}", text); + } + + // Write a main() that will print some text. + fn main() { + print("Hello, World"); + } + "#, + ) + } + /// Install a local wasm-bindgen for this fixture. /// /// Takes care not to re-install for every fixture, but only the one time @@ -221,7 +257,7 @@ impl Fixture { static INSTALL_WASM_BINDGEN: Once = ONCE_INIT; let cache = self.cache(); - let version = "0.2.37"; + let version = "0.2.54"; let download = || { if let Ok(download) = @@ -316,6 +352,12 @@ impl Fixture { Cache::at(&self.cache_dir()) } + pub fn command>(&self, program: S) -> Command { + let mut result = Command::new(program); + result.current_dir(&self.path); + result + } + /// The `step_install_wasm_bindgen` and `step_run_wasm_bindgen` steps only /// occur after the `step_build_wasm` step. In order to read the lockfile /// in the test fixture's temporary directory, we should first build the @@ -415,6 +457,86 @@ pub fn no_cdylib() -> Fixture { fixture } +pub fn bin_crate() -> Fixture { + let fixture = Fixture::new(); + fixture.readme().hello_world_src_main().file( + "Cargo.toml", + r#" + [package] + authors = ["The wasm-pack developers"] + description = "so awesome rust+wasm package" + license = "WTFPL" + name = "foo" + repository = "https://github.com/rustwasm/wasm-pack.git" + version = "0.1.0" + + [dependencies] + wasm-bindgen = "0.2" + + [dev-dependencies] + wasm-bindgen-test = "0.2" + "#, + ); + fixture +} + +pub fn multi_bin_crate() -> Fixture { + let fixture = Fixture::new(); + fixture + .readme() + .hello_world_src_main() + .file( + "src/bin/sample.rs", + r#" + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + + // Import the `console.log` function from the Web. + #[wasm_bindgen] + extern { + #[wasm_bindgen(js_namespace = console, js_name = log)] + fn console_log(s: &str); + } + + // On wasm, print() should forward to console.log. + #[cfg(target_arch = "wasm32")] + fn print(text: &str) { + console_log(text); + } + + // On not-wasm, print() should forward to println!(). + #[cfg(not(target_arch = "wasm32"))] + fn print(text: &str) { + println!("{}", text); + } + + // Write a main() that will print slightly different text. + fn main() { + print("Sample Text"); + } + "#, + ) + .file( + "Cargo.toml", + r#" + [package] + authors = ["The wasm-pack developers"] + description = "so awesome rust+wasm package" + license = "WTFPL" + name = "foo" + repository = "https://github.com/rustwasm/wasm-pack.git" + version = "0.1.0" + + [dependencies] + wasm-bindgen = "0.2" + + [dev-dependencies] + wasm-bindgen-test = "0.2" + "#, + ); + fixture +} + pub fn not_a_crate() -> Fixture { let fixture = Fixture::new(); fixture.file("README.md", "This is not a Rust crate!"); From 5b0d6a975fa11801491d439dc534af9b0bb05ff9 Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Mon, 9 Dec 2019 22:19:34 -0700 Subject: [PATCH 2/5] terrible ad hoc example handling --- src/bindgen.rs | 14 +++++++++- src/manifest/mod.rs | 2 +- tests/all/build.rs | 20 +++++++++++++ tests/all/utils/fixture.rs | 57 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 2 deletions(-) diff --git a/src/bindgen.rs b/src/bindgen.rs index eea7e504..202850f4 100644 --- a/src/bindgen.rs +++ b/src/bindgen.rs @@ -33,9 +33,21 @@ pub fn wasm_bindgen_build( .target_directory() .join("wasm32-unknown-unknown") .join(release_or_debug) - .join(target_name) + .join(&target_name) .with_extension("wasm"); + // TODO have a better way to detect examples + let wasm_path = if wasm_path.exists() { + wasm_path + } else { + data.target_directory() + .join("wasm32-unknown-unknown") + .join(release_or_debug) + .join("examples") + .join(target_name) + .with_extension("wasm") + }; + let dts_arg = if disable_dts { "--no-typescript" } else { diff --git a/src/manifest/mod.rs b/src/manifest/mod.rs index 8fc0166c..db710f67 100644 --- a/src/manifest/mod.rs +++ b/src/manifest/mod.rs @@ -495,7 +495,7 @@ impl CrateData { fn valid_targets(&self) -> impl Iterator { fn valid_kind(x: &str) -> bool { - x == "cdylib" || x == "bin" + x == "cdylib" || x == "bin" || x == "example" } let pkg = &self.data.packages[self.current_idx]; pkg.targets diff --git a/tests/all/build.rs b/tests/all/build.rs index e32ec7f1..c81a2004 100644 --- a/tests/all/build.rs +++ b/tests/all/build.rs @@ -335,3 +335,23 @@ fn multi_bin_crate_procs_all() { assert!(pkg_path("foo.js").exists()); assert!(pkg_path("sample.js").exists()); } + +#[test] +fn builds_examples() { + let fixture = utils::fixture::bin_example_crate(); + fixture.install_local_wasm_bindgen(); + fixture + .wasm_pack() + .arg("build") + .arg("--target") + .arg("nodejs") + .arg("--") + .arg("--bins") + .arg("--examples") + .assert() + .success(); + let mut path = fixture.path.clone(); + path.push("pkg"); + path.push("example.js"); + assert!(path.exists()); +} diff --git a/tests/all/utils/fixture.rs b/tests/all/utils/fixture.rs index 9e0d4c47..fd19fd23 100644 --- a/tests/all/utils/fixture.rs +++ b/tests/all/utils/fixture.rs @@ -537,6 +537,63 @@ pub fn multi_bin_crate() -> Fixture { fixture } +pub fn bin_example_crate() -> Fixture { + let fixture = Fixture::new(); + fixture + .readme() + .hello_world_src_main() + .file( + "examples/example.rs", + r#" + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + + // Import the `console.log` function from the Web. + #[wasm_bindgen] + extern { + #[wasm_bindgen(js_namespace = console, js_name = log)] + fn console_log(s: &str); + } + + // On wasm, print() should forward to console.log. + #[cfg(target_arch = "wasm32")] + fn print(text: &str) { + console_log(text); + } + + // On not-wasm, print() should forward to println!(). + #[cfg(not(target_arch = "wasm32"))] + fn print(text: &str) { + println!("{}", text); + } + + // Write a main() that will print slightly different text. + fn main() { + print("Sample Text"); + } + "#, + ) + .file( + "Cargo.toml", + r#" + [package] + authors = ["The wasm-pack developers"] + description = "so awesome rust+wasm package" + license = "WTFPL" + name = "foo" + repository = "https://github.com/rustwasm/wasm-pack.git" + version = "0.1.0" + + [dependencies] + wasm-bindgen = "0.2" + + [dev-dependencies] + wasm-bindgen-test = "0.2" + "#, + ); + fixture +} + pub fn not_a_crate() -> Fixture { let fixture = Fixture::new(); fixture.file("README.md", "This is not a Rust crate!"); From 804428c6ab6f50e670d3730de3d937226466fb01 Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Tue, 10 Dec 2019 14:41:42 -0700 Subject: [PATCH 3/5] slightly better example handling --- src/bindgen.rs | 24 +++++++++------------- src/build/mod.rs | 4 ++++ src/command/build.rs | 11 ++++++++-- src/command/test.rs | 2 +- src/manifest/mod.rs | 23 ++++++++++++++++----- tests/all/build.rs | 5 ++--- tests/all/license.rs | 10 ++++----- tests/all/lockfile.rs | 8 ++++---- tests/all/manifest.rs | 48 +++++++++++++++++++++---------------------- 9 files changed, 77 insertions(+), 58 deletions(-) diff --git a/src/bindgen.rs b/src/bindgen.rs index 202850f4..13573e3a 100644 --- a/src/bindgen.rs +++ b/src/bindgen.rs @@ -29,21 +29,17 @@ pub fn wasm_bindgen_build( let out_dir = out_dir.to_str().unwrap(); for target_name in data.targets() { - let wasm_path = data - .target_directory() - .join("wasm32-unknown-unknown") - .join(release_or_debug) - .join(&target_name) - .with_extension("wasm"); - - // TODO have a better way to detect examples - let wasm_path = if wasm_path.exists() { - wasm_path - } else { - data.target_directory() + let wasm_path = { + let wasm_path = data + .target_directory() .join("wasm32-unknown-unknown") - .join(release_or_debug) - .join("examples") + .join(release_or_debug); + let wasm_path = if data.is_example() { + wasm_path.join("examples") + } else { + wasm_path + }; + wasm_path .join(target_name) .with_extension("wasm") }; diff --git a/src/build/mod.rs b/src/build/mod.rs index d9fd6220..b7d496b2 100644 --- a/src/build/mod.rs +++ b/src/build/mod.rs @@ -76,6 +76,7 @@ fn wasm_pack_local_version() -> Option { pub fn cargo_build_wasm( path: &Path, profile: BuildProfile, + example: &Option, extra_options: &[String], ) -> Result<(), Error> { let msg = format!("{}Compiling to Wasm...", emoji::CYCLONE); @@ -100,6 +101,9 @@ pub fn cargo_build_wasm( } } cmd.arg("--target").arg("wasm32-unknown-unknown"); + if let Some(example) = example { + cmd.arg("--example").arg(example); + } cmd.args(extra_options); child::run(cmd, "cargo build").context("Compiling your crate to WebAssembly failed")?; Ok(()) diff --git a/src/command/build.rs b/src/command/build.rs index 723f5074..cb92ed2b 100644 --- a/src/command/build.rs +++ b/src/command/build.rs @@ -34,6 +34,7 @@ pub struct Build { pub out_name: Option, pub bindgen: Option, pub cache: Cache, + pub example: Option, pub extra_options: Vec, } @@ -148,6 +149,10 @@ pub struct BuildOptions { /// Sets the output file names. Defaults to package name. pub out_name: Option, + #[structopt(long = "example")] + /// Builds the specified example. + pub example: Option, + #[structopt(last = true)] /// List of extra options to pass to `cargo build` pub extra_options: Vec, @@ -167,6 +172,7 @@ impl Default for BuildOptions { profiling: false, out_dir: String::new(), out_name: None, + example: None, extra_options: Vec::new(), } } @@ -178,7 +184,7 @@ impl Build { /// Construct a build command from the given options. pub fn try_from_opts(build_opts: BuildOptions) -> Result { let crate_path = get_crate_path(build_opts.path)?; - let crate_data = manifest::CrateData::new(&crate_path, build_opts.out_name.clone())?; + let crate_data = manifest::CrateData::new(&crate_path, build_opts.out_name.clone(), build_opts.example.clone())?; let out_dir = crate_path.join(PathBuf::from(build_opts.out_dir)); let dev = build_opts.dev || build_opts.debug; @@ -203,6 +209,7 @@ impl Build { out_name: build_opts.out_name, bindgen: None, cache: cache::get_wasm_pack_cache()?, + example: build_opts.example, extra_options: build_opts.extra_options, }) } @@ -298,7 +305,7 @@ impl Build { fn step_build_wasm(&mut self) -> Result<(), Error> { info!("Building wasm..."); - build::cargo_build_wasm(&self.crate_path, self.profile, &self.extra_options)?; + build::cargo_build_wasm(&self.crate_path, self.profile, &self.example, &self.extra_options)?; info!( "wasm built at {:#?}.", diff --git a/src/command/test.rs b/src/command/test.rs index 8bf262d2..89dd9e93 100644 --- a/src/command/test.rs +++ b/src/command/test.rs @@ -119,7 +119,7 @@ impl Test { } = test_opts; let crate_path = get_crate_path(path)?; - let crate_data = manifest::CrateData::new(&crate_path, None)?; + let crate_data = manifest::CrateData::new(&crate_path, None, None)?; let any_browser = chrome || firefox || safari; if !node && !any_browser { diff --git a/src/manifest/mod.rs b/src/manifest/mod.rs index db710f67..cec6ec98 100644 --- a/src/manifest/mod.rs +++ b/src/manifest/mod.rs @@ -39,6 +39,7 @@ pub struct CrateData { current_idx: usize, manifest: CargoManifest, out_name: Option, + example: Option, } #[doc(hidden)] @@ -402,7 +403,7 @@ pub struct ManifestAndUnsedKeys { impl CrateData { /// Reads all metadata for the crate whose manifest is inside the directory /// specified by `path`. - pub fn new(crate_path: &Path, out_name: Option) -> Result { + pub fn new(crate_path: &Path, out_name: Option, example: Option) -> Result { let manifest_path = crate_path.join("Cargo.toml"); if !manifest_path.is_file() { bail!( @@ -431,6 +432,7 @@ impl CrateData { manifest, current_idx, out_name, + example, }) } @@ -494,14 +496,20 @@ impl CrateData { } fn valid_targets(&self) -> impl Iterator { - fn valid_kind(x: &str) -> bool { - x == "cdylib" || x == "bin" || x == "example" + fn valid(target: &cargo_metadata::Target, example: &Option) -> bool { + if let Some(example) = example { + target.name == *example && target.kind.iter().any(|k| k == "example") + } else { + fn valid_kind(x: &str) -> bool { + x == "cdylib" || x == "bin" + } + target.kind.iter().any(|x| valid_kind(x)) + } } let pkg = &self.data.packages[self.current_idx]; pkg.targets .iter() - .filter(|target| target.kind.iter().any(|k| valid_kind(k))) - .filter(|target| target.crate_types.iter().any(|s| valid_kind(s))) + .filter(move |target| valid(target, &self.example)) } fn check_crate_type(&self) -> Result<(), Error> { @@ -541,6 +549,11 @@ impl CrateData { }) } + /// Check if we are building an example. + pub fn is_example(&self) -> bool { + self.example.is_some() + } + /// Get the prefix for output file names pub fn name_prefix(&self) -> String { match &self.out_name { diff --git a/tests/all/build.rs b/tests/all/build.rs index c81a2004..74603def 100644 --- a/tests/all/build.rs +++ b/tests/all/build.rs @@ -345,9 +345,8 @@ fn builds_examples() { .arg("build") .arg("--target") .arg("nodejs") - .arg("--") - .arg("--bins") - .arg("--examples") + .arg("--example") + .arg("example") .assert() .success(); let mut path = fixture.path.clone(); diff --git a/tests/all/license.rs b/tests/all/license.rs index cffa7995..eb69ab0b 100644 --- a/tests/all/license.rs +++ b/tests/all/license.rs @@ -12,7 +12,7 @@ fn it_copies_a_license_default_path() { let fixture = fixture::single_license(); let out_dir = fixture.path.join("pkg"); fs::create_dir(&out_dir).expect("should create pkg directory OK"); - let crate_data = CrateData::new(&fixture.path, None); + let crate_data = CrateData::new(&fixture.path, None, None); assert!(license::copy_from_crate(&crate_data.unwrap(), &fixture.path, &out_dir).is_ok()); @@ -37,7 +37,7 @@ fn it_copies_a_license_provided_path() { let fixture = fixture::single_license(); let out_dir = fixture.path.join("pkg"); fs::create_dir(&out_dir).expect("should create pkg directory OK"); - let crate_data = CrateData::new(&fixture.path, None); + let crate_data = CrateData::new(&fixture.path, None, None); assert!(license::copy_from_crate(&crate_data.unwrap(), &fixture.path, &out_dir).is_ok()); let crate_license_path = fixture.path.join("LICENSE"); @@ -60,7 +60,7 @@ fn it_copies_all_licenses_default_path() { let fixture = fixture::dual_license(); let out_dir = fixture.path.join("pkg"); fs::create_dir(&out_dir).expect("should create pkg directory OK"); - let crate_data = CrateData::new(&fixture.path, None); + let crate_data = CrateData::new(&fixture.path, None, None); assert!(license::copy_from_crate(&crate_data.unwrap(), &fixture.path, &out_dir).is_ok()); @@ -95,7 +95,7 @@ fn it_copies_all_licenses_provided_path() { let fixture = fixture::dual_license(); let out_dir = fixture.path.join("pkg"); fs::create_dir(&out_dir).expect("should create pkg directory OK"); - let crate_data = CrateData::new(&fixture.path, None); + let crate_data = CrateData::new(&fixture.path, None, None); assert!(license::copy_from_crate(&crate_data.unwrap(), &fixture.path, &out_dir).is_ok()); @@ -131,7 +131,7 @@ fn it_copies_a_non_standard_license_provided_path() { let fixture = fixture::non_standard_license(license_file); let out_dir = fixture.path.join("pkg"); fs::create_dir(&out_dir).expect("should create pkg directory OK"); - let crate_data = CrateData::new(&fixture.path, None); + let crate_data = CrateData::new(&fixture.path, None, None); assert!(license::copy_from_crate(&crate_data.unwrap(), &fixture.path, &out_dir).is_ok()); diff --git a/tests/all/lockfile.rs b/tests/all/lockfile.rs index 1a42ce88..d4a4e418 100644 --- a/tests/all/lockfile.rs +++ b/tests/all/lockfile.rs @@ -6,7 +6,7 @@ use wasm_pack::manifest::CrateData; fn it_gets_wasm_bindgen_version() { let fixture = fixture::js_hello_world(); fixture.cargo_check(); - let data = CrateData::new(&fixture.path, None).unwrap(); + let data = CrateData::new(&fixture.path, None, None).unwrap(); let lock = Lockfile::new(&data).unwrap(); assert_eq!(lock.wasm_bindgen_version(), Some("0.2.37"),); } @@ -15,7 +15,7 @@ fn it_gets_wasm_bindgen_version() { fn it_gets_wasm_bindgen_test_version() { let fixture = fixture::wbg_test_node(); fixture.cargo_check(); - let data = CrateData::new(&fixture.path, None).unwrap(); + let data = CrateData::new(&fixture.path, None, None).unwrap(); let lock = Lockfile::new(&data).unwrap(); assert_eq!(lock.wasm_bindgen_test_version(), Some("0.2.37"),); } @@ -60,7 +60,7 @@ fn it_gets_wasm_bindgen_version_in_crate_inside_workspace() { "#, ); fixture.cargo_check(); - let data = CrateData::new(&fixture.path.join("blah"), None).unwrap(); + let data = CrateData::new(&fixture.path.join("blah"), None, None).unwrap(); let lock = Lockfile::new(&data).unwrap(); assert_eq!(lock.wasm_bindgen_version(), Some("0.2.37"),); } @@ -128,7 +128,7 @@ fn it_gets_wasm_bindgen_version_from_dependencies() { "#, ); fixture.cargo_check(); - let data = CrateData::new(&fixture.path.join("parent"), None).unwrap(); + let data = CrateData::new(&fixture.path.join("parent"), None, None).unwrap(); let lock = Lockfile::new(&data).unwrap(); assert_eq!(lock.wasm_bindgen_version(), Some("0.2.37"),); } diff --git a/tests/all/manifest.rs b/tests/all/manifest.rs index 1a46c71a..3ee0b934 100644 --- a/tests/all/manifest.rs +++ b/tests/all/manifest.rs @@ -10,7 +10,7 @@ use wasm_pack::{self, license, manifest}; #[test] fn it_gets_the_crate_name_default_path() { let path = &PathBuf::from("."); - let crate_data = manifest::CrateData::new(&path, None).unwrap(); + let crate_data = manifest::CrateData::new(&path, None, None).unwrap(); let name = crate_data.crate_name(); assert_eq!(name, "wasm_pack"); } @@ -18,14 +18,14 @@ fn it_gets_the_crate_name_default_path() { #[test] fn it_gets_the_crate_name_provided_path() { let fixture = fixture::js_hello_world(); - let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None, None).unwrap(); assert_eq!(crate_data.crate_name(), "js_hello_world"); } #[test] fn it_gets_the_default_name_prefix() { let path = &PathBuf::from("."); - let crate_data = manifest::CrateData::new(&path, None).unwrap(); + let crate_data = manifest::CrateData::new(&path, None, None).unwrap(); let name = crate_data.name_prefix(); assert_eq!(name, "wasm_pack"); } @@ -33,7 +33,7 @@ fn it_gets_the_default_name_prefix() { #[test] fn it_gets_the_name_prefix_passed_from_cli() { let path = &PathBuf::from("."); - let crate_data = manifest::CrateData::new(&path, Some("index".to_owned())).unwrap(); + let crate_data = manifest::CrateData::new(&path, Some("index".to_owned()), None).unwrap(); let name = crate_data.name_prefix(); assert_eq!(name, "index"); } @@ -43,7 +43,7 @@ fn it_checks_has_cdylib_default_path() { let fixture = fixture::no_cdylib(); // Ensure that there is a `Cargo.lock`. fixture.cargo_check(); - let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None, None).unwrap(); assert!(crate_data.check_crate_config().is_err()); } @@ -52,21 +52,21 @@ fn it_checks_has_cdylib_provided_path() { let fixture = fixture::js_hello_world(); // Ensure that there is a `Cargo.lock`. fixture.cargo_check(); - let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None, None).unwrap(); crate_data.check_crate_config().unwrap(); } #[test] fn it_checks_has_cdylib_wrong_crate_type() { let fixture = fixture::bad_cargo_toml(); - let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None, None).unwrap(); assert!(crate_data.check_crate_config().is_err()); } #[test] fn it_accepts_binary_crates_without_cdylib() { let fixture = fixture::bin_crate(); - let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None, None).unwrap(); crate_data.check_crate_config().unwrap(); } @@ -75,7 +75,7 @@ fn it_recognizes_a_map_during_depcheck() { let fixture = fixture::serde_feature(); // Ensure that there is a `Cargo.lock`. fixture.cargo_check(); - let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None, None).unwrap(); crate_data.check_crate_config().unwrap(); } @@ -83,7 +83,7 @@ fn it_recognizes_a_map_during_depcheck() { fn it_creates_a_package_json_default_path() { let fixture = fixture::js_hello_world(); let out_dir = fixture.path.join("pkg"); - let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None, None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); assert!(crate_data .write_package_json(&out_dir, &None, false, Target::Bundler) @@ -118,7 +118,7 @@ fn it_creates_a_package_json_default_path() { fn it_creates_a_package_json_provided_path() { let fixture = fixture::js_hello_world(); let out_dir = fixture.path.join("pkg"); - let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None, None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); assert!(crate_data .write_package_json(&out_dir, &None, false, Target::Bundler) @@ -146,7 +146,7 @@ fn it_creates_a_package_json_provided_path() { fn it_creates_a_package_json_provided_path_with_scope() { let fixture = fixture::js_hello_world(); let out_dir = fixture.path.join("pkg"); - let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None, None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); assert!(crate_data .write_package_json(&out_dir, &Some("test".to_string()), false, Target::Bundler,) @@ -174,7 +174,7 @@ fn it_creates_a_package_json_provided_path_with_scope() { fn it_creates_a_pkg_json_with_correct_files_on_node() { let fixture = fixture::js_hello_world(); let out_dir = fixture.path.join("pkg"); - let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None, None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); assert!(crate_data .write_package_json(&out_dir, &None, false, Target::Nodejs) @@ -209,7 +209,7 @@ fn it_creates_a_pkg_json_with_correct_files_on_node() { fn it_creates_a_pkg_json_with_correct_files_on_nomodules() { let fixture = fixture::js_hello_world(); let out_dir = fixture.path.join("pkg"); - let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None, None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); assert!(crate_data .write_package_json(&out_dir, &None, false, Target::NoModules) @@ -243,7 +243,7 @@ fn it_creates_a_pkg_json_with_correct_files_on_nomodules() { fn it_creates_a_package_json_with_correct_files_when_out_name_is_provided() { let fixture = fixture::js_hello_world(); let out_dir = fixture.path.join("pkg"); - let crate_data = manifest::CrateData::new(&fixture.path, Some("index".to_owned())).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, Some("index".to_owned()), None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); assert!(crate_data .write_package_json(&out_dir, &None, false, Target::Bundler) @@ -274,7 +274,7 @@ fn it_creates_a_package_json_with_correct_files_when_out_name_is_provided() { fn it_creates_a_pkg_json_in_out_dir() { let fixture = fixture::js_hello_world(); let out_dir = fixture.path.join("./custom/out"); - let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None, None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); assert!(crate_data .write_package_json(&out_dir, &None, false, Target::Bundler) @@ -289,7 +289,7 @@ fn it_creates_a_pkg_json_in_out_dir() { fn it_creates_a_package_json_with_correct_keys_when_types_are_skipped() { let fixture = fixture::js_hello_world(); let out_dir = fixture.path.join("pkg"); - let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None, None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); assert!(crate_data .write_package_json(&out_dir, &None, true, Target::Bundler) @@ -317,7 +317,7 @@ fn it_creates_a_package_json_with_correct_keys_when_types_are_skipped() { #[test] fn it_errors_when_wasm_bindgen_is_not_declared() { let fixture = fixture::bad_cargo_toml(); - let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None, None).unwrap(); assert!(crate_data.check_crate_config().is_err()); } @@ -349,7 +349,7 @@ fn it_sets_homepage_field_if_available_in_cargo_toml() { ); let out_dir = fixture.path.join("pkg"); - let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None, None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); crate_data @@ -365,7 +365,7 @@ fn it_sets_homepage_field_if_available_in_cargo_toml() { // When 'homepage' is unavailable let fixture = fixture::js_hello_world(); let out_dir = fixture.path.join("pkg"); - let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None, None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); crate_data @@ -381,7 +381,7 @@ fn it_does_not_error_when_wasm_bindgen_is_declared() { let fixture = fixture::js_hello_world(); // Ensure that there is a `Cargo.lock`. fixture.cargo_check(); - let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None, None).unwrap(); crate_data.check_crate_config().unwrap(); } @@ -465,7 +465,7 @@ fn it_lists_license_files_in_files_field_of_package_json() { let fixture = fixture::dual_license(); let out_dir = fixture.path.join("pkg"); - let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None, None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); license::copy_from_crate(&crate_data, &fixture.path, &out_dir).unwrap(); @@ -507,7 +507,7 @@ fn it_recurses_up_the_path_to_find_cargo_toml() { "#, ); let path = get_crate_path(None).unwrap(); - let crate_data = manifest::CrateData::new(&path, None).unwrap(); + let crate_data = manifest::CrateData::new(&path, None, None).unwrap(); let name = crate_data.crate_name(); assert_eq!(name, "wasm_pack"); } @@ -529,6 +529,6 @@ fn it_doesnt_recurse_up_the_path_to_find_cargo_toml_when_default() { "#, ); let path = get_crate_path(Some(PathBuf::from("src"))).unwrap(); - let crate_data = manifest::CrateData::new(&path, None); + let crate_data = manifest::CrateData::new(&path, None, None); assert!(crate_data.is_err()); } From a415c7b8af5e939b74bdf2720b393d915ae8e2cd Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Tue, 10 Dec 2019 17:41:54 -0700 Subject: [PATCH 4/5] appease cargo fmt --- src/bindgen.rs | 4 +--- src/command/build.rs | 13 +++++++++++-- src/manifest/mod.rs | 6 +++++- tests/all/manifest.rs | 3 ++- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/bindgen.rs b/src/bindgen.rs index 13573e3a..c7d47de3 100644 --- a/src/bindgen.rs +++ b/src/bindgen.rs @@ -39,9 +39,7 @@ pub fn wasm_bindgen_build( } else { wasm_path }; - wasm_path - .join(target_name) - .with_extension("wasm") + wasm_path.join(target_name).with_extension("wasm") }; let dts_arg = if disable_dts { diff --git a/src/command/build.rs b/src/command/build.rs index cb92ed2b..d4a0ed48 100644 --- a/src/command/build.rs +++ b/src/command/build.rs @@ -184,7 +184,11 @@ impl Build { /// Construct a build command from the given options. pub fn try_from_opts(build_opts: BuildOptions) -> Result { let crate_path = get_crate_path(build_opts.path)?; - let crate_data = manifest::CrateData::new(&crate_path, build_opts.out_name.clone(), build_opts.example.clone())?; + let crate_data = manifest::CrateData::new( + &crate_path, + build_opts.out_name.clone(), + build_opts.example.clone(), + )?; let out_dir = crate_path.join(PathBuf::from(build_opts.out_dir)); let dev = build_opts.dev || build_opts.debug; @@ -305,7 +309,12 @@ impl Build { fn step_build_wasm(&mut self) -> Result<(), Error> { info!("Building wasm..."); - build::cargo_build_wasm(&self.crate_path, self.profile, &self.example, &self.extra_options)?; + build::cargo_build_wasm( + &self.crate_path, + self.profile, + &self.example, + &self.extra_options, + )?; info!( "wasm built at {:#?}.", diff --git a/src/manifest/mod.rs b/src/manifest/mod.rs index cec6ec98..8e388959 100644 --- a/src/manifest/mod.rs +++ b/src/manifest/mod.rs @@ -403,7 +403,11 @@ pub struct ManifestAndUnsedKeys { impl CrateData { /// Reads all metadata for the crate whose manifest is inside the directory /// specified by `path`. - pub fn new(crate_path: &Path, out_name: Option, example: Option) -> Result { + pub fn new( + crate_path: &Path, + out_name: Option, + example: Option, + ) -> Result { let manifest_path = crate_path.join("Cargo.toml"); if !manifest_path.is_file() { bail!( diff --git a/tests/all/manifest.rs b/tests/all/manifest.rs index 3ee0b934..e25f684a 100644 --- a/tests/all/manifest.rs +++ b/tests/all/manifest.rs @@ -243,7 +243,8 @@ fn it_creates_a_pkg_json_with_correct_files_on_nomodules() { fn it_creates_a_package_json_with_correct_files_when_out_name_is_provided() { let fixture = fixture::js_hello_world(); let out_dir = fixture.path.join("pkg"); - let crate_data = manifest::CrateData::new(&fixture.path, Some("index".to_owned()), None).unwrap(); + let crate_data = + manifest::CrateData::new(&fixture.path, Some("index".to_owned()), None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); assert!(crate_data .write_package_json(&out_dir, &None, false, Target::Bundler) From 559879530ec3736daf3061eaf0acb88b4b55767f Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Fri, 10 Jan 2020 19:21:29 -0700 Subject: [PATCH 5/5] skip binaries that don't exist this handles, e.g., binaries missing required features --- src/bindgen.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bindgen.rs b/src/bindgen.rs index c7d47de3..b809d343 100644 --- a/src/bindgen.rs +++ b/src/bindgen.rs @@ -42,6 +42,10 @@ pub fn wasm_bindgen_build( wasm_path.join(target_name).with_extension("wasm") }; + if !wasm_path.exists() { + continue; + } + let dts_arg = if disable_dts { "--no-typescript" } else {