Merge pull request #312 from rustwasm/mod-mod-mod

modules modules modules
master
Michael Gattozzi 7 years ago committed by GitHub
commit 1e9d8de32c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 143
      src/manifest/mod.rs
  2. 20
      src/manifest/npm/commonjs.rs
  3. 22
      src/manifest/npm/esmodules.rs
  4. 13
      src/manifest/npm/mod.rs
  5. 6
      src/manifest/npm/repository.rs
  6. 44
      tests/all/manifest.rs
  7. 12
      tests/all/utils/manifest.rs

@ -1,10 +1,13 @@
//! Reading and writing Cargo.toml and package.json manifests.
mod npm;
use std::collections::HashMap;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;
use self::npm::{repository::Repository, CommonJSPackage, ESModulesPackage, NpmPackage};
use console::style;
use emoji;
use error::Error;
@ -57,6 +60,27 @@ struct CargoPackage {
repository: Option<String>,
}
impl CargoPackage {
fn check_optional_fields(&self) {
let warn_fmt = |field| {
format!(
"Field '{}' is missing from Cargo.toml. It is not necessary, but recommended",
field
)
};
if self.description.is_none() {
PBAR.warn(&warn_fmt("description"));
}
if self.repository.is_none() {
PBAR.warn(&warn_fmt("repository"));
}
if self.license.is_none() {
PBAR.warn(&warn_fmt("license"));
}
}
}
#[derive(Debug, Deserialize)]
#[serde(untagged)]
enum CargoDependency {
@ -75,32 +99,6 @@ struct CargoLib {
crate_type: Option<Vec<String>>,
}
#[derive(Serialize)]
struct NpmPackage {
name: String,
#[serde(skip_serializing_if = "Vec::is_empty")]
collaborators: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
description: Option<String>,
version: String,
#[serde(skip_serializing_if = "Option::is_none")]
license: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
repository: Option<Repository>,
#[serde(skip_serializing_if = "Vec::is_empty")]
files: Vec<String>,
main: String,
#[serde(skip_serializing_if = "Option::is_none")]
types: Option<String>,
}
#[derive(Serialize)]
struct Repository {
#[serde(rename = "type")]
ty: String,
url: String,
}
fn read_cargo_toml(path: &Path) -> Result<CargoManifest, Error> {
let manifest_path = path.join("Cargo.toml");
if !manifest_path.is_file() {
@ -120,19 +118,55 @@ fn read_cargo_toml(path: &Path) -> Result<CargoManifest, Error> {
}
impl CargoManifest {
fn into_npm(mut self, scope: &Option<String>, disable_dts: bool, target: &str) -> NpmPackage {
fn into_commonjs(mut self, scope: &Option<String>, disable_dts: bool) -> NpmPackage {
let filename = self.package.name.replace("-", "_");
let wasm_file = format!("{}_bg.wasm", filename);
let js_file = format!("{}.js", filename);
let mut files = vec![wasm_file];
let dts_file = if disable_dts == true {
None
let js_bg_file = format!("{}_bg.js", filename);
files.push(js_bg_file.to_string());
if let Some(s) = scope {
self.package.name = format!("@{}/{}", s, self.package.name);
}
let dts_file = if disable_dts == false {
let file = format!("{}.d.ts", filename);
files.push(file.to_string());
Some(file)
} else {
Some(format!("{}.d.ts", filename))
None
};
let js_bg_file = if target == "nodejs" {
Some(format!("{}_bg.js", filename))
&self.package.check_optional_fields();
NpmPackage::CommonJSPackage(CommonJSPackage {
name: self.package.name,
collaborators: self.package.authors,
description: self.package.description,
version: self.package.version,
license: self.package.license,
repository: self.package.repository.map(|repo_url| Repository {
ty: "git".to_string(),
url: repo_url,
}),
files: files,
main: js_file,
types: dts_file,
})
}
fn into_esmodules(mut self, scope: &Option<String>, disable_dts: bool) -> NpmPackage {
let filename = self.package.name.replace("-", "_");
let wasm_file = format!("{}_bg.wasm", filename);
let js_file = format!("{}.js", filename);
let mut files = vec![wasm_file, js_file.clone()];
let dts_file = if disable_dts == false {
let file = format!("{}.d.ts", filename);
files.push(file.to_string());
Some(file)
} else {
None
};
@ -140,23 +174,10 @@ impl CargoManifest {
if let Some(s) = scope {
self.package.name = format!("@{}/{}", s, self.package.name);
}
let mut files = vec![wasm_file];
match dts_file {
Some(ref dts_file) => {
files.push(dts_file.to_string());
}
None => {}
}
match js_bg_file {
Some(ref js_bg_file) => {
files.push(js_bg_file.to_string());
}
None => {}
}
&self.package.check_optional_fields();
NpmPackage {
NpmPackage::ESModulesPackage(ESModulesPackage {
name: self.package.name,
collaborators: self.package.authors,
description: self.package.description,
@ -167,9 +188,10 @@ impl CargoManifest {
url: repo_url,
}),
files: files,
main: js_file,
module: js_file,
types: dts_file,
}
side_effects: "false".to_string(),
})
}
}
@ -184,28 +206,15 @@ pub fn write_package_json(
) -> Result<(), Error> {
let msg = format!("{}Writing a package.json...", emoji::MEMO);
let warn_fmt = |field| {
format!(
"Field '{}' is missing from Cargo.toml. It is not necessary, but recommended",
field
)
};
PBAR.step(step, &msg);
let pkg_file_path = out_dir.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);
if npm_data.description.is_none() {
PBAR.warn(&warn_fmt("description"));
}
if npm_data.repository.is_none() {
PBAR.warn(&warn_fmt("repository"));
}
if npm_data.license.is_none() {
PBAR.warn(&warn_fmt("license"));
}
let npm_data = if target == "nodejs" {
crate_data.into_commonjs(scope, disable_dts)
} else {
crate_data.into_esmodules(scope, disable_dts)
};
let npm_json = serde_json::to_string_pretty(&npm_data)?;
pkg_file.write_all(npm_json.as_bytes())?;

@ -0,0 +1,20 @@
use manifest::npm::repository::Repository;
#[derive(Serialize)]
pub struct CommonJSPackage {
pub name: String,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub collaborators: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub version: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub license: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub repository: Option<Repository>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub files: Vec<String>,
pub main: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub types: Option<String>,
}

@ -0,0 +1,22 @@
use manifest::npm::repository::Repository;
#[derive(Serialize)]
pub struct ESModulesPackage {
pub name: String,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub collaborators: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub version: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub license: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub repository: Option<Repository>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub files: Vec<String>,
pub module: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub types: Option<String>,
#[serde(rename = "sideEffects")]
pub side_effects: String,
}

@ -0,0 +1,13 @@
mod commonjs;
mod esmodules;
pub mod repository;
pub use self::commonjs::CommonJSPackage;
pub use self::esmodules::ESModulesPackage;
#[derive(Serialize)]
#[serde(untagged)]
pub enum NpmPackage {
CommonJSPackage(CommonJSPackage),
ESModulesPackage(ESModulesPackage),
}

@ -0,0 +1,6 @@
#[derive(Serialize)]
pub struct Repository {
#[serde(rename = "type")]
pub ty: String,
pub url: String,
}

@ -68,12 +68,12 @@ fn it_creates_a_package_json_default_path() {
pkg.repository.url,
"https://github.com/ashleygwilliams/wasm-pack.git"
);
assert_eq!(pkg.main, "wasm_pack.js");
let types = pkg.types.unwrap_or_default();
assert_eq!(types, "wasm_pack.d.ts");
assert_eq!(pkg.module, "wasm_pack.js");
assert_eq!(pkg.types, "wasm_pack.d.ts");
assert_eq!(pkg.side_effects, "false");
let actual_files: HashSet<String> = pkg.files.into_iter().collect();
let expected_files: HashSet<String> = ["wasm_pack_bg.wasm", "wasm_pack.d.ts"]
let expected_files: HashSet<String> = ["wasm_pack_bg.wasm", "wasm_pack.d.ts", "wasm_pack.js"]
.iter()
.map(|&s| String::from(s))
.collect();
@ -92,10 +92,14 @@ fn it_creates_a_package_json_provided_path() {
assert!(utils::manifest::read_package_json(&fixture.path, &out_dir).is_ok());
let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
assert_eq!(pkg.name, "js-hello-world");
assert_eq!(pkg.main, "js_hello_world.js");
assert_eq!(pkg.module, "js_hello_world.js");
let actual_files: HashSet<String> = pkg.files.into_iter().collect();
let expected_files: HashSet<String> = ["js_hello_world_bg.wasm", "js_hello_world.d.ts"]
let expected_files: HashSet<String> = [
"js_hello_world_bg.wasm",
"js_hello_world.d.ts",
"js_hello_world.js",
]
.iter()
.map(|&s| String::from(s))
.collect();
@ -123,10 +127,14 @@ fn it_creates_a_package_json_provided_path_with_scope() {
assert!(utils::manifest::read_package_json(&fixture.path, &out_dir).is_ok());
let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
assert_eq!(pkg.name, "@test/scopes-hello-world");
assert_eq!(pkg.main, "scopes_hello_world.js");
assert_eq!(pkg.module, "scopes_hello_world.js");
let actual_files: HashSet<String> = pkg.files.into_iter().collect();
let expected_files: HashSet<String> = ["scopes_hello_world_bg.wasm", "scopes_hello_world.d.ts"]
let expected_files: HashSet<String> = [
"scopes_hello_world_bg.wasm",
"scopes_hello_world.d.ts",
"scopes_hello_world.js",
]
.iter()
.map(|&s| String::from(s))
.collect();
@ -154,8 +162,7 @@ fn it_creates_a_pkg_json_with_correct_files_on_node() {
"https://github.com/ashleygwilliams/wasm-pack.git"
);
assert_eq!(pkg.main, "wasm_pack.js");
let types = pkg.types.unwrap_or_default();
assert_eq!(types, "wasm_pack.d.ts");
assert_eq!(pkg.types, "wasm_pack.d.ts");
let actual_files: HashSet<String> = pkg.files.into_iter().collect();
let expected_files: HashSet<String> =
@ -177,19 +184,6 @@ fn it_creates_a_pkg_json_in_out_dir() {
let package_json_path = &fixture.path.join(&out_dir).join("package.json");
assert!(fs::metadata(package_json_path).is_ok());
assert!(utils::manifest::read_package_json(&fixture.path, &out_dir).is_ok());
let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
assert_eq!(pkg.name, "js-hello-world");
assert_eq!(pkg.main, "js_hello_world.js");
let actual_files: HashSet<String> = pkg.files.into_iter().collect();
let expected_files: HashSet<String> = ["js_hello_world_bg.wasm", "js_hello_world.d.ts"]
.iter()
.map(|&s| String::from(s))
.collect();
assert_eq!(actual_files, expected_files);
}
#[test]
@ -209,10 +203,10 @@ fn it_creates_a_package_json_with_correct_keys_when_types_are_skipped() {
pkg.repository.url,
"https://github.com/ashleygwilliams/wasm-pack.git"
);
assert_eq!(pkg.main, "wasm_pack.js");
assert_eq!(pkg.module, "wasm_pack.js");
let actual_files: HashSet<String> = pkg.files.into_iter().collect();
let expected_files: HashSet<String> = ["wasm_pack_bg.wasm"]
let expected_files: HashSet<String> = ["wasm_pack_bg.wasm", "wasm_pack.js"]
.iter()
.map(|&s| String::from(s))
.collect();

@ -13,8 +13,18 @@ pub struct NpmPackage {
pub license: String,
pub repository: Repository,
pub files: Vec<String>,
#[serde(default = "default_none")]
pub main: String,
pub types: Option<String>,
#[serde(default = "default_none")]
pub module: String,
#[serde(default = "default_none")]
pub types: String,
#[serde(default = "default_none", rename = "sideEffects")]
pub side_effects: String,
}
fn default_none() -> String {
"".to_string()
}
#[derive(Deserialize)]

Loading…
Cancel
Save