Skip to content
This repository has been archived by the owner on Nov 8, 2021. It is now read-only.

Commit

Permalink
Merge pull request rustwasm#446 from drager/catch-types-in-cargo-toml
Browse files Browse the repository at this point in the history
feat: Catch typos in Cargo.toml and warn about them
  • Loading branch information
ashleygwilliams authored Dec 21, 2018
2 parents fa5e39b + 07d813f commit 8ed6e3d
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 12 deletions.
17 changes: 17 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ openssl = { version = '0.10.11', optional = true }
parking_lot = "0.6"
serde = "1.0.74"
serde_derive = "1.0.74"
serde_ignored = "0.0.4"
serde_json = "1.0.26"
siphasher = "0.2.3"
slog = "2.3"
slog-term = "2.4"
slog-async = "2.3"
strsim = "0.8.0"
structopt = "0.2"
tar = "0.4.16"
toml = "0.4"
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ extern crate cargo_metadata;
extern crate console;
extern crate curl;
extern crate dirs;
extern crate strsim;
#[macro_use]
extern crate failure;
extern crate flate2;
Expand All @@ -18,6 +19,7 @@ extern crate parking_lot;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_ignored;
extern crate serde_json;
extern crate siphasher;
#[macro_use]
Expand Down
65 changes: 60 additions & 5 deletions src/manifest/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,23 @@ use failure::{Error, ResultExt};
use progressbar::Step;
use serde::{self, Deserialize};
use serde_json;
use std::collections::BTreeSet;
use strsim::levenshtein;
use toml;
use PBAR;

const WASM_PACK_METADATA_KEY: &'static str = "package.metadata.wasm-pack";

/// Store for metadata learned about a crate
pub struct CrateData {
data: Metadata,
current_idx: usize,
manifest: CargoManifest,
}

#[doc(hidden)]
#[derive(Deserialize)]
struct CargoManifest {
pub struct CargoManifest {
package: CargoPackage,
}

Expand Down Expand Up @@ -196,6 +201,12 @@ struct NpmData {
main: String,
}

#[doc(hidden)]
pub struct ManifestAndUnsedKeys {
pub manifest: CargoManifest,
pub unused_keys: BTreeSet<String>,
}

impl CrateData {
/// Reads all metadata for the crate whose manifest is inside the directory
/// specified by `path`.
Expand All @@ -208,14 +219,14 @@ impl CrateData {
crate_path.display()
)
}
let manifest = fs::read_to_string(&manifest_path)
.with_context(|_| format!("failed to read: {}", manifest_path.display()))?;
let manifest: CargoManifest = toml::from_str(&manifest)
.with_context(|_| format!("failed to parse manifest: {}", manifest_path.display()))?;

let data =
cargo_metadata::metadata(Some(&manifest_path)).map_err(error_chain_to_failure)?;

let manifest_and_keys = CrateData::parse_crate_data(&manifest_path)?;
CrateData::warn_for_unused_keys(&manifest_and_keys);

let manifest = manifest_and_keys.manifest;
let current_idx = data
.packages
.iter()
Expand All @@ -241,6 +252,50 @@ impl CrateData {
}
}

/// Read the `manifest_path` file and deserializes it using the toml Deserializer.
/// Returns a Result containing `ManifestAndUnsedKeys` which contains `CargoManifest`
/// and a `BTreeSet<String>` containing the unused keys from the parsed file.
///
/// # Errors
/// Will return Err if the file (manifest_path) couldn't be read or
/// if deserialize to `CargoManifest` fails.
pub fn parse_crate_data(manifest_path: &Path) -> Result<ManifestAndUnsedKeys, Error> {
let manifest = fs::read_to_string(&manifest_path)
.with_context(|_| format!("failed to read: {}", manifest_path.display()))?;
let manifest = &mut toml::Deserializer::new(&manifest);

let mut unused_keys = BTreeSet::new();
let levenshtein_threshold = 1;

let manifest: CargoManifest = serde_ignored::deserialize(manifest, |path| {
let path_string = path.to_string();

if path_string.starts_with("package.metadata")
&& (path_string.contains("wasm-pack")
|| levenshtein(WASM_PACK_METADATA_KEY, &path_string) <= levenshtein_threshold)
{
unused_keys.insert(path_string);
}
})
.with_context(|_| format!("failed to parse manifest: {}", manifest_path.display()))?;

Ok(ManifestAndUnsedKeys {
manifest,
unused_keys,
})
}

/// Iterating through all the passed `unused_keys` and output
/// a warning for each unknown key.
pub fn warn_for_unused_keys(manifest_and_keys: &ManifestAndUnsedKeys) {
manifest_and_keys.unused_keys.iter().for_each(|path| {
PBAR.warn(&format!(
"\"{}\" is a unknown key and will be ignored. Please check your Cargo.toml.",
path
));
});
}

/// Get the configured profile.
pub fn configured_profile(&self, profile: BuildProfile) -> &CargoWasmPackProfile {
match profile {
Expand Down
49 changes: 42 additions & 7 deletions tests/all/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,11 +292,9 @@ fn it_does_not_error_when_wasm_bindgen_is_declared() {
#[test]
fn configure_wasm_bindgen_debug_incorrectly_is_error() {
let fixture = utils::fixture::Fixture::new();
fixture
.readme()
.file(
"Cargo.toml",
r#"
fixture.readme().hello_world_src_lib().file(
"Cargo.toml",
r#"
[package]
authors = ["The wasm-pack developers"]
description = "so awesome rust+wasm package"
Expand All @@ -314,8 +312,7 @@ fn configure_wasm_bindgen_debug_incorrectly_is_error() {
[package.metadata.wasm-pack.profile.dev.wasm-bindgen]
debug-js-glue = "not a boolean"
"#,
)
.hello_world_src_lib();
);

let cli = Cli::from_iter_safe(vec![
"wasm-pack",
Expand All @@ -333,3 +330,41 @@ fn configure_wasm_bindgen_debug_incorrectly_is_error() {
.to_string()
.contains("package.metadata.wasm-pack.profile.dev.wasm-bindgen.debug")));
}

#[test]
fn parse_crate_data_returns_unused_keys_in_cargo_toml() {
let fixture = utils::fixture::Fixture::new();
fixture
.readme()
.file(
"Cargo.toml",
r#"
[package]
authors = ["The wasm-pack developers"]
description = "so awesome rust+wasm package"
license = "WTFPL"
name = "whatever"
repository = "https://github.com/rustwasm/wasm-pack.git"
version = "0.1.0"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "0.2"
# Note: production is not valid.
[package.metadata.wasm-pack.profile.production.wasm-bindgen]
debug-js-glue = true
"#,
)
.hello_world_src_lib();

let result = manifest::CrateData::parse_crate_data(&fixture.path.join("Cargo.toml"));

assert!(result.is_ok());

let manifest::ManifestAndUnsedKeys { unused_keys, .. } = result.unwrap();

assert!(unused_keys.contains("package.metadata.wasm-pack.profile.production"));
}

0 comments on commit 8ed6e3d

Please sign in to comment.