Skip to content

Commit ae10c23

Browse files
authored
Merge pull request #986 from jpgneves/implement-rfc-8
Implements RFC 8, fixing #606
2 parents 68e6de2 + d79e721 commit ae10c23

File tree

7 files changed

+105
-9
lines changed

7 files changed

+105
-9
lines changed

src/command/utils.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ fn find_manifest_from_cwd() -> Result<PathBuf, failure::Error> {
3737

3838
/// Construct our `pkg` directory in the crate.
3939
pub fn create_pkg_dir(out_dir: &Path) -> Result<(), failure::Error> {
40+
let _ = fs::remove_dir_all(&out_dir); // Clean up any existing directory and ignore errors
4041
fs::create_dir_all(&out_dir)?;
4142
fs::write(out_dir.join(".gitignore"), "*")?;
4243
Ok(())

src/manifest/mod.rs

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99
mod npm;
1010

11-
use std::fs;
1211
use std::path::Path;
12+
use std::{collections::HashMap, fs};
1313

1414
use self::npm::{
1515
repository::Repository, CommonJSPackage, ESModulesPackage, NoModulesPackage, NpmPackage,
@@ -575,14 +575,25 @@ impl CrateData {
575575
target: Target,
576576
) -> Result<(), Error> {
577577
let pkg_file_path = out_dir.join("package.json");
578+
// Check if a `package.json` was already generated by wasm-bindgen, if so
579+
// we merge the NPM dependencies already specified in it.
580+
let existing_deps = if pkg_file_path.exists() {
581+
// It's just a map of dependency names to versions
582+
Some(serde_json::from_str::<HashMap<String, String>>(
583+
&fs::read_to_string(&pkg_file_path)?,
584+
)?)
585+
} else {
586+
None
587+
};
578588
let npm_data = match target {
579-
Target::Nodejs => self.to_commonjs(scope, disable_dts, out_dir),
580-
Target::NoModules => self.to_nomodules(scope, disable_dts, out_dir),
581-
Target::Bundler => self.to_esmodules(scope, disable_dts, out_dir),
582-
Target::Web => self.to_web(scope, disable_dts, out_dir),
589+
Target::Nodejs => self.to_commonjs(scope, disable_dts, existing_deps, out_dir),
590+
Target::NoModules => self.to_nomodules(scope, disable_dts, existing_deps, out_dir),
591+
Target::Bundler => self.to_esmodules(scope, disable_dts, existing_deps, out_dir),
592+
Target::Web => self.to_web(scope, disable_dts, existing_deps, out_dir),
583593
};
584594

585595
let npm_json = serde_json::to_string_pretty(&npm_data)?;
596+
586597
fs::write(&pkg_file_path, npm_json)
587598
.with_context(|_| format!("failed to write: {}", pkg_file_path.display()))?;
588599
Ok(())
@@ -657,7 +668,13 @@ impl CrateData {
657668
})
658669
}
659670

660-
fn to_commonjs(&self, scope: &Option<String>, disable_dts: bool, out_dir: &Path) -> NpmPackage {
671+
fn to_commonjs(
672+
&self,
673+
scope: &Option<String>,
674+
disable_dts: bool,
675+
dependencies: Option<HashMap<String, String>>,
676+
out_dir: &Path,
677+
) -> NpmPackage {
661678
let data = self.npm_data(scope, false, disable_dts, out_dir);
662679
let pkg = &self.data.packages[self.current_idx];
663680

@@ -683,13 +700,15 @@ impl CrateData {
683700
homepage: data.homepage,
684701
types: data.dts_file,
685702
keywords: data.keywords,
703+
dependencies,
686704
})
687705
}
688706

689707
fn to_esmodules(
690708
&self,
691709
scope: &Option<String>,
692710
disable_dts: bool,
711+
dependencies: Option<HashMap<String, String>>,
693712
out_dir: &Path,
694713
) -> NpmPackage {
695714
let data = self.npm_data(scope, true, disable_dts, out_dir);
@@ -718,10 +737,17 @@ impl CrateData {
718737
types: data.dts_file,
719738
side_effects: false,
720739
keywords: data.keywords,
740+
dependencies,
721741
})
722742
}
723743

724-
fn to_web(&self, scope: &Option<String>, disable_dts: bool, out_dir: &Path) -> NpmPackage {
744+
fn to_web(
745+
&self,
746+
scope: &Option<String>,
747+
disable_dts: bool,
748+
dependencies: Option<HashMap<String, String>>,
749+
out_dir: &Path,
750+
) -> NpmPackage {
725751
let data = self.npm_data(scope, false, disable_dts, out_dir);
726752
let pkg = &self.data.packages[self.current_idx];
727753

@@ -748,13 +774,15 @@ impl CrateData {
748774
types: data.dts_file,
749775
side_effects: false,
750776
keywords: data.keywords,
777+
dependencies,
751778
})
752779
}
753780

754781
fn to_nomodules(
755782
&self,
756783
scope: &Option<String>,
757784
disable_dts: bool,
785+
dependencies: Option<HashMap<String, String>>,
758786
out_dir: &Path,
759787
) -> NpmPackage {
760788
let data = self.npm_data(scope, false, disable_dts, out_dir);
@@ -782,6 +810,7 @@ impl CrateData {
782810
homepage: data.homepage,
783811
types: data.dts_file,
784812
keywords: data.keywords,
813+
dependencies,
785814
})
786815
}
787816

src/manifest/npm/commonjs.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::collections::HashMap;
2+
13
use manifest::npm::repository::Repository;
24

35
#[derive(Serialize)]
@@ -21,4 +23,6 @@ pub struct CommonJSPackage {
2123
pub types: Option<String>,
2224
#[serde(skip_serializing_if = "Option::is_none")]
2325
pub keywords: Option<Vec<String>>,
26+
#[serde(skip_serializing_if = "Option::is_none")]
27+
pub dependencies: Option<HashMap<String, String>>,
2428
}

src/manifest/npm/esmodules.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::collections::HashMap;
2+
13
use manifest::npm::repository::Repository;
24

35
#[derive(Serialize)]
@@ -23,4 +25,6 @@ pub struct ESModulesPackage {
2325
pub side_effects: bool,
2426
#[serde(skip_serializing_if = "Option::is_none")]
2527
pub keywords: Option<Vec<String>>,
28+
#[serde(skip_serializing_if = "Option::is_none")]
29+
pub dependencies: Option<HashMap<String, String>>,
2630
}

src/manifest/npm/nomodules.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::collections::HashMap;
2+
13
use manifest::npm::repository::Repository;
24

35
#[derive(Serialize)]
@@ -21,4 +23,6 @@ pub struct NoModulesPackage {
2123
pub types: Option<String>,
2224
#[serde(skip_serializing_if = "Option::is_none")]
2325
pub keywords: Option<Vec<String>>,
26+
#[serde(skip_serializing_if = "Option::is_none")]
27+
pub dependencies: Option<HashMap<String, String>>,
2428
}

tests/all/manifest.rs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use assert_cmd::prelude::*;
2-
use std::collections::HashSet;
2+
use std::collections::{HashMap, HashSet};
33
use std::fs;
44
use std::path::PathBuf;
55
use utils::{self, fixture};
@@ -314,6 +314,54 @@ fn it_creates_a_package_json_with_correct_keys_when_types_are_skipped() {
314314
assert_eq!(actual_files, expected_files);
315315
}
316316

317+
#[test]
318+
fn it_creates_a_package_json_with_npm_dependencies_provided_by_wasm_bindgen() {
319+
let fixture = fixture::js_hello_world();
320+
let out_dir = fixture.path.join("pkg");
321+
let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();
322+
wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap();
323+
// Write a `package.json` in the out_dir, as wasm-bindgen does:
324+
utils::manifest::create_wbg_package_json(
325+
&out_dir,
326+
r#"
327+
{ "foo": "^1.2.3" }
328+
"#,
329+
)
330+
.unwrap();
331+
assert!(crate_data
332+
.write_package_json(&out_dir, &None, true, Target::Bundler)
333+
.is_ok());
334+
let package_json_path = &out_dir.join("package.json");
335+
fs::metadata(package_json_path).unwrap();
336+
utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
337+
let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
338+
assert_eq!(pkg.name, "js-hello-world");
339+
assert_eq!(pkg.repository.ty, "git");
340+
assert_eq!(
341+
pkg.repository.url,
342+
"https://github.com/rustwasm/wasm-pack.git"
343+
);
344+
assert_eq!(pkg.module, "js_hello_world.js");
345+
346+
let actual_files: HashSet<String> = pkg.files.into_iter().collect();
347+
let expected_files: HashSet<String> = [
348+
"js_hello_world_bg.wasm",
349+
"js_hello_world_bg.js",
350+
"js_hello_world.js",
351+
]
352+
.iter()
353+
.map(|&s| String::from(s))
354+
.collect();
355+
assert_eq!(actual_files, expected_files);
356+
357+
let dependencies: Option<HashMap<String, String>> = pkg.dependencies;
358+
assert!(dependencies.is_some());
359+
let mut expected_dependencies: HashMap<String, String> = HashMap::new();
360+
expected_dependencies.insert("foo".to_owned(), "^1.2.3".to_owned());
361+
362+
assert_eq!(dependencies.unwrap(), expected_dependencies);
363+
}
364+
317365
#[test]
318366
fn it_errors_when_wasm_bindgen_is_not_declared() {
319367
let fixture = fixture::bad_cargo_toml();

tests/all/utils/manifest.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use std::fs::File;
21
use std::io::prelude::*;
32
use std::path::Path;
3+
use std::{collections::HashMap, fs::File};
44

55
use failure::Error;
66
use serde_json;
@@ -25,6 +25,7 @@ pub struct NpmPackage {
2525
pub side_effects: bool,
2626
pub homepage: Option<String>,
2727
pub keywords: Option<Vec<String>>,
28+
pub dependencies: Option<HashMap<String, String>>,
2829
}
2930

3031
fn default_none() -> String {
@@ -50,3 +51,8 @@ pub fn read_package_json(path: &Path, out_dir: &Path) -> Result<NpmPackage, Erro
5051

5152
Ok(serde_json::from_str(&pkg_contents)?)
5253
}
54+
55+
pub fn create_wbg_package_json(out_dir: &Path, contents: &str) -> Result<(), Error> {
56+
let manifest_path = out_dir.join("package.json");
57+
Ok(std::fs::write(manifest_path, contents)?)
58+
}

0 commit comments

Comments
 (0)