wasm-bindgen/crates/web-sys/build.rs
Alex Crichton 935f71afec
Switch from failure to anyhow (#1851)
This commit switches all of `wasm-bindgen` from the `failure` crate to
`anyhow`. The `anyhow` crate should serve all the purposes that we
previously used `failure` for but has a few advantages:

* It's based on the standard `Error` trait rather than a custom `Fail`
  trait, improving ecosystem compatibility.
* We don't need a `#[derive(Fail)]`, which means that's less code to
  compile for `wasm-bindgen`. This notably helps the compile time of
  `web-sys` itself.
* Using `Result<()>` in `fn main` with `anyhow::Error` produces
  human-readable output, so we can use that natively.
2019-11-04 11:35:28 -06:00

102 lines
3.8 KiB
Rust

use anyhow::{Context, Result};
use sourcefile::SourceFile;
use std::collections::HashSet;
use std::env;
use std::ffi::OsStr;
use std::fs;
use std::path::{self, PathBuf};
use std::process::Command;
fn main() -> Result<()> {
#[cfg(feature = "env_logger")]
env_logger::init();
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=webidls/enabled");
let entries = fs::read_dir("webidls/enabled").context("reading webidls/enabled directory")?;
let mut source = SourceFile::default();
for entry in entries {
let entry = entry.context("getting webidls/enabled/*.webidl entry")?;
let path = entry.path();
if path.extension() != Some(OsStr::new("webidl")) {
continue;
}
println!("cargo:rerun-if-changed={}", path.display());
source = source
.add_file(&path)
.with_context(|| format!("reading contents of file \"{}\"", path.display()))?;
}
// Read our manifest, learn all `[feature]` directives with "toml parsing".
// Use all these names to match against environment variables set by Cargo
// to figure out which features are activated to we can pass that down to
// the webidl compiler.
let manifest_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap());
let manifest = fs::read_to_string(manifest_dir.join("Cargo.toml"))?;
let features = manifest
.lines()
.skip_while(|f| !f.starts_with("[features]"));
let enabled_features = env::vars()
.map(|p| p.0)
.filter(|p| p.starts_with("CARGO_FEATURE_"))
.map(|mut p| {
p.drain(0.."CARGO_FEATURE_".len());
p
})
.collect::<HashSet<_>>();
let mut allowed = Vec::new();
for feature in features.filter(|f| !f.starts_with("#") && !f.starts_with("[")) {
let mut parts = feature.split('=');
let name = parts.next().unwrap().trim();
if enabled_features.contains(&name.to_uppercase()) {
allowed.push(name);
}
}
// If we're printing all features don't filter anything
println!("cargo:rerun-if-env-changed=__WASM_BINDGEN_DUMP_FEATURES");
let allowed = if env::var("__WASM_BINDGEN_DUMP_FEATURES").is_ok() {
None
} else {
Some(&allowed[..])
};
let bindings = match wasm_bindgen_webidl::compile(&source.contents, allowed) {
Ok(bindings) => bindings,
Err(e) => {
if let Some(err) = e.downcast_ref::<wasm_bindgen_webidl::WebIDLParseError>() {
if let Some(pos) = source.resolve_offset(err.0) {
let ctx = format!(
"compiling WebIDL into wasm-bindgen bindings in file \
\"{}\", line {} column {}",
pos.filename,
pos.line + 1,
pos.col + 1
);
return Err(e.context(ctx));
} else {
return Err(e.context("compiling WebIDL into wasm-bindgen bindings"));
}
}
return Err(e.context("compiling WebIDL into wasm-bindgen bindings"));
}
};
let out_dir = env::var("OUT_DIR").context("reading OUT_DIR environment variable")?;
let out_file_path = path::Path::new(&out_dir).join("bindings.rs");
fs::write(&out_file_path, bindings).context("writing bindings to output file")?;
println!("cargo:rustc-env=BINDINGS={}", out_file_path.display());
// run rustfmt on the generated file - really handy for debugging
//
// This is opportunistic though so don't assert that it succeeds.
println!("cargo:rerun-if-env-changed=WEBIDL_RUSTFMT_BINDINGS");
if env::var("WEBIDL_RUSTFMT_BINDINGS").ok() != Some("0".to_string()) {
drop(Command::new("rustfmt").arg(&out_file_path).status());
}
Ok(())
}