Skip to content

Commit

Permalink
Use --message-format=json to fix #333
Browse files Browse the repository at this point in the history
  • Loading branch information
konstin committed Sep 24, 2018
1 parent 4c9d308 commit 0bd1dc7
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 37 deletions.
24 changes: 24 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ tar = "0.4.16"
toml = "0.4"
which = "2.0.0"
zip = "0.4.2"
cargo_metadata = { git = "https://github.com/roblabla/cargo_metadata", rev = "54a24e30864feb7414ca400f65a486d1e01ec474" }

[dev-dependencies]
tempfile = "3"
Expand Down
11 changes: 2 additions & 9 deletions src/bindgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ pub fn cargo_install_wasm_bindgen(crate_path: &Path, version: &str) -> Result<()
pub fn wasm_bindgen_build(
path: &Path,
out_dir: &Path,
name: &str,
artifact: &Path,
disable_dts: bool,
target: &str,
debug: bool,
Expand All @@ -119,16 +119,9 @@ pub fn wasm_bindgen_build(
let msg = format!("{}Running WASM-bindgen...", emoji::RUNNER);
PBAR.step(step, &msg);

let binary_name = name.replace("-", "_");
let release_or_debug = if debug { "debug" } else { "release" };

let out_dir = out_dir.to_str().unwrap();

if let Some(wasm_bindgen_path) = wasm_bindgen_path(log, path) {
let wasm_path = format!(
"target/wasm32-unknown-unknown/{}/{}.wasm",
release_or_debug, binary_name
);
let dts_arg = if disable_dts {
"--no-typescript"
} else {
Expand All @@ -142,7 +135,7 @@ pub fn wasm_bindgen_build(
let bindgen_path = Path::new(&wasm_bindgen_path);
let mut cmd = Command::new(bindgen_path);
cmd.current_dir(path)
.arg(&wasm_path)
.arg(artifact)
.arg("--out-dir")
.arg(out_dir)
.arg(dts_arg)
Expand Down
88 changes: 71 additions & 17 deletions src/build.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
//! Building a Rust crate into a `.wasm` binary.
use cargo_metadata;
use cargo_metadata::Message;
use emoji;
use error::Error;
use progressbar::Step;
use std::io::Read;
use std::path::Path;
use std::path::PathBuf;
use std::process::Command;
use std::process::Stdio;
use PBAR;

/// Ensure that `rustup` has the `wasm32-unknown-unknown` target installed for
Expand Down Expand Up @@ -47,27 +52,76 @@ fn ensure_nightly() -> Result<(), Error> {

/// Run `cargo build` with the `nightly` toolchain and targetting
/// `wasm32-unknown-unknown`.
pub fn cargo_build_wasm(path: &Path, debug: bool, step: &Step) -> Result<(), Error> {
///
/// Returns the location of the built wasm file.
pub fn cargo_build_wasm(
path: &Path,
debug: bool,
step: &Step,
crate_name: &str,
) -> Result<PathBuf, Error> {
let msg = format!("{}Compiling to WASM...", emoji::CYCLONE);
PBAR.step(step, &msg);
let output = {
let mut cmd = Command::new("cargo");
cmd.current_dir(path)
.arg("+nightly")
.arg("build")
.arg("--lib");
if !debug {
cmd.arg("--release");
}
cmd.arg("--target").arg("wasm32-unknown-unknown");
cmd.output()?
};

if !output.status.success() {
let s = String::from_utf8_lossy(&output.stderr);
Error::cli("Compilation of your program failed", s)
let mut cmd = Command::new("cargo");
cmd.current_dir(path)
.arg("+nightly")
.arg("build")
.arg("--lib")
.arg("--target=wasm32-unknown-unknown")
.arg("--message-format=json")
.stderr(Stdio::piped())
.stdout(Stdio::piped());
if !debug {
cmd.arg("--release");
}
let mut output = cmd.spawn()?;

let message_stream = output
.stdout
.take()
.expect("cargo child process should always have an stdout");

let mut wasm_file = None;

for message in cargo_metadata::parse_message_stream(message_stream) {
match message.unwrap() {
Message::CompilerArtifact(artifact) => {
if artifact.package_id.name() == crate_name {
let pos = artifact
.target
.crate_types
.iter()
.position(|x| x == "cdylib");

if let Some(pos) = pos {
wasm_file = Some(PathBuf::from(&artifact.filenames[pos]));
};
};
}
_ => (),
};
}

let status = output.wait()?;
if !status.success() {
let mut stderr = String::new();
output
.stderr
.expect("stderr must exist")
.read_to_string(&mut stderr)?;
Err(Error::Cli {
message: "Compilation of your program failed".to_string(),
stderr,
})
} else {
Ok(())
if let Some(wasm_file) = wasm_file {
Ok(wasm_file)
} else {
Err(Error::CrateConfig {
message: "Your crate didn't produce a cdylib".to_string(),
})
}
}
}

Expand Down
21 changes: 10 additions & 11 deletions src/command/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ pub(crate) struct Build {
// build_config: Option<BuildConfig>,
pub crate_name: String,
pub out_dir: PathBuf,
/// This is a workaround to pass the artifact's location from build_wasm to run_wasm_bindgen
pub wasm_file: Option<PathBuf>,
}

/// The `BuildMode` determines which mode of initialization we are running, and
Expand Down Expand Up @@ -109,6 +111,7 @@ impl Build {
// build_config,
crate_name,
out_dir,
wasm_file: None,
})
}

Expand Down Expand Up @@ -191,17 +194,13 @@ impl Build {

fn step_build_wasm(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
info!(&log, "Building wasm...");
build::cargo_build_wasm(&self.crate_path, self.debug, step)?;
let artifact =
build::cargo_build_wasm(&self.crate_path, self.debug, step, &self.crate_name)?;

info!(&log, "wasm built at {:#?}.", &artifact);

self.wasm_file = Some(artifact);

info!(
&log,
"wasm built at {:#?}.",
&self
.crate_path
.join("target")
.join("wasm32-unknown-unknown")
.join("release")
);
Ok(())
}

Expand Down Expand Up @@ -270,7 +269,7 @@ impl Build {
bindgen::wasm_bindgen_build(
&self.crate_path,
&self.out_dir,
&self.crate_name,
&self.wasm_file.clone().unwrap(),
self.disable_dts,
&self.target,
self.debug,
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ extern crate serde_json;
extern crate structopt;
#[macro_use]
extern crate slog;
extern crate cargo_metadata;
extern crate slog_async;
extern crate slog_term;
extern crate tar;
Expand Down
18 changes: 18 additions & 0 deletions tests/all/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,21 @@ fn build_in_non_crate_directory_doesnt_panic() {
let err_msg = result.unwrap_err().to_string();
assert!(err_msg.contains("missing a `Cargo.toml`"));
}

#[test]
fn build_in_nested_workspace() {
let fixture = utils::fixture::nested_workspace();
let cli = Cli::from_iter_safe(vec![
"wasm-pack",
"build",
"--debug",
"--mode=no-install",
&fixture.path.join("sub-crate").display().to_string(),
]).unwrap();
let logger = logger::new(&cli.cmd, cli.verbosity).unwrap();
let result = command::run_wasm_pack(cli.cmd, &logger);
assert!(
result.is_ok(),
"Building with wasm-pack in nested workspace should succeed"
);
}
48 changes: 48 additions & 0 deletions tests/all/utils/fixture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ impl Fixture {
)
}

pub fn hello_world_src_lib(&self) -> &Self {
self.hello_world_with_path("src/lib.rs")
}

/// Install a local wasm-bindgen for this fixture.
///
/// Takes care not to re-install for every fixture, but only the one time
Expand Down Expand Up @@ -453,3 +457,47 @@ pub fn with_underscores() -> Fixture {
);
fixture
}

pub fn nested_workspace() -> Fixture {
let fixture = Fixture::new();

// The upper crate
fixture
.readme()
.file(
"src/lib.rs",
r#"
compile_error!("Wrong crate");
"#,
).file(
"Cargo.toml",
r#"
[package]
name = "main-crate"
version = "0.1.0"
authors = ["The wasm-pack developers"]
[workspace]
members = [
"sub-crate"
]
"#,
);

fixture.hello_world_with_path("sub-crate/src/lib.rs").file(
"sub-crate/Cargo.toml",
r#"
[package]
name = "sub-crate"
version = "0.1.0"
authors = ["The wasm-pack developers"]
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "0.2"
"#,
);
fixture
}

0 comments on commit 0bd1dc7

Please sign in to comment.