Skip to content

Commit 489ffce

Browse files
committed
Coordinate wasm-bindgen versions.
1 parent 969797c commit 489ffce

File tree

7 files changed

+188
-47
lines changed

7 files changed

+188
-47
lines changed

Cargo.lock

Lines changed: 16 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ slog-term = "2.4"
2323
slog-async = "2.3"
2424
structopt = "0.2"
2525
toml = "0.4"
26+
which = "2.0.0"
2627

2728
[dev-dependencies]
2829
copy_dir = "0.1.2"

src/bindgen.rs

Lines changed: 118 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,57 @@
33
use emoji;
44
use error::Error;
55
use progressbar::Step;
6-
use std::path::Path;
6+
use std::path::{Path, PathBuf};
77
use std::process::Command;
8+
use which::which;
89
use PBAR;
910

1011
/// Install the `wasm-bindgen` CLI with `cargo install`.
11-
pub fn cargo_install_wasm_bindgen(step: &Step) -> Result<(), Error> {
12+
pub fn cargo_install_wasm_bindgen(
13+
path: &Path,
14+
version: &str,
15+
install_permitted: bool,
16+
step: &Step,
17+
) -> Result<(), Error> {
18+
// Determine if the `wasm-bindgen` dependency is already met for the given mode.
19+
let dependency_met = if let Some(bindgen_path) = wasm_bindgen_path_str(path) {
20+
wasm_bindgen_version_check(&bindgen_path, version).unwrap_or_else(|_| false)
21+
} else {
22+
false
23+
};
24+
25+
// If the `wasm-bindgen` dependency is already met, print a message and return.
26+
if dependency_met {
27+
let msg = format!("{}WASM-bindgen already installed...", emoji::DOWN_ARROW);
28+
PBAR.step(step, &msg);
29+
return Ok(());
30+
}
31+
32+
// If the `wasm-bindgen` dependency was not met, and installs are not
33+
// permitted, return a configuration error.
34+
if !install_permitted {
35+
return Error::crate_config("WASM-bindgen is not installed!");
36+
// FIXUP: This error message can be improved.
37+
}
38+
1239
let msg = format!("{}Installing WASM-bindgen...", emoji::DOWN_ARROW);
1340
PBAR.step(step, &msg);
1441
let output = Command::new("cargo")
1542
.arg("install")
16-
.arg("wasm-bindgen-cli")
1743
.arg("--force")
44+
.arg("wasm-bindgen-cli")
45+
.arg("--version")
46+
.arg(version)
47+
.arg("--root")
48+
.arg(path)
1849
.output()?;
1950
if !output.status.success() {
51+
let message = "Installing wasm-bindgen failed".to_string();
2052
let s = String::from_utf8_lossy(&output.stderr);
21-
if s.contains("already exists") {
22-
PBAR.info("wasm-bindgen already installed");
23-
return Ok(());
24-
}
25-
Error::cli("Installing wasm-bindgen failed", s)
53+
Err(Error::Cli {
54+
message,
55+
stderr: s.to_string(),
56+
})
2657
} else {
2758
Ok(())
2859
}
@@ -42,33 +73,88 @@ pub fn wasm_bindgen_build(
4273
PBAR.step(step, &msg);
4374
let binary_name = name.replace("-", "_");
4475
let release_or_debug = if debug { "debug" } else { "release" };
45-
let wasm_path = format!(
46-
"target/wasm32-unknown-unknown/{}/{}.wasm",
47-
release_or_debug, binary_name
48-
);
49-
let dts_arg = if disable_dts == false {
50-
"--typescript"
51-
} else {
52-
"--no-typescript"
53-
};
5476

55-
let target_arg = match target {
56-
"nodejs" => "--nodejs",
57-
_ => "--browser",
58-
};
77+
if let Some(wasm_bindgen_path_str) = wasm_bindgen_path_str(path) {
78+
let wasm_path = format!(
79+
"target/wasm32-unknown-unknown/{}/{}.wasm",
80+
release_or_debug, binary_name
81+
);
82+
let dts_arg = if disable_dts == false {
83+
"--typescript"
84+
} else {
85+
"--no-typescript"
86+
};
87+
let target_arg = match target {
88+
"nodejs" => "--nodejs",
89+
_ => "--browser",
90+
};
91+
let bindgen_path = Path::new(&wasm_bindgen_path_str);
92+
let output = Command::new(bindgen_path)
93+
.current_dir(path)
94+
.arg(&wasm_path)
95+
.arg("--out-dir")
96+
.arg("./pkg")
97+
.arg(dts_arg)
98+
.arg(target_arg)
99+
.output()?;
100+
if !output.status.success() {
101+
let s = String::from_utf8_lossy(&output.stderr);
102+
Error::cli("wasm-bindgen failed to execute properly", s)
103+
} else {
104+
Ok(())
105+
}
106+
} else {
107+
Error::crate_config("Could not find `wasm-bindgen`")
108+
}
109+
}
59110

60-
let output = Command::new("wasm-bindgen")
61-
.current_dir(path)
62-
.arg(&wasm_path)
63-
.arg("--out-dir")
64-
.arg("./pkg")
65-
.arg(dts_arg)
66-
.arg(target_arg)
67-
.output()?;
68-
if !output.status.success() {
111+
/// Check if the `wasm-bindgen` dependency is locally satisfied.
112+
fn wasm_bindgen_version_check(bindgen_path: &PathBuf, dep_version: &str) -> Result<bool, Error> {
113+
let wasm_bindgen = Path::new(bindgen_path);
114+
let output = Command::new(wasm_bindgen).arg("--version").output()?;
115+
if output.status.success() {
116+
let s = String::from_utf8_lossy(&output.stdout);
117+
let installed_version = s.trim(); // FIXUP: Trim this more thoroughly?
118+
Ok(installed_version == dep_version)
119+
} else {
120+
// FIXUP: This error message can be improved.
121+
let message = String::from("Could not find version of local wasm-bindgen");
69122
let s = String::from_utf8_lossy(&output.stderr);
70-
Error::cli("wasm-bindgen failed to execute properly", s)
123+
Err(Error::Cli {
124+
message,
125+
stderr: s.to_string(),
126+
})
127+
}
128+
}
129+
130+
/// Return a string to `wasm-bindgen`, if it exists for the given mode.
131+
fn wasm_bindgen_path_str(crate_path: &Path) -> Option<PathBuf> {
132+
if let res @ Some(_) = local_wasm_bindgen_path_str(crate_path) {
133+
res
134+
} else if let res @ Some(_) = global_wasm_bindgen_path_str() {
135+
res
71136
} else {
72-
Ok(())
137+
None
138+
}
139+
}
140+
141+
/// Return a string containing the path to the local `wasm-bindgen`, if it exists.
142+
fn local_wasm_bindgen_path_str(crate_path: &Path) -> Option<PathBuf> {
143+
let mut path = crate_path.to_path_buf();
144+
path.push("bin");
145+
path.push("wasm-bindgen");
146+
if path.is_file() {
147+
Some(path)
148+
} else {
149+
None
150+
}
151+
}
152+
153+
/// Return a string containing the path to the global `wasm-bindgen`, if it exists.
154+
fn global_wasm_bindgen_path_str() -> Option<PathBuf> {
155+
if let Ok(path) = which("wasm-bindgen") {
156+
Some(path)
157+
} else {
158+
None
73159
}
74160
}

src/command/build.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub(crate) struct Build {
1919
pub disable_dts: bool,
2020
pub target: String,
2121
pub debug: bool,
22+
pub mode: BuildMode,
2223
// build_config: Option<BuildConfig>,
2324
pub crate_name: String,
2425
}
@@ -71,21 +72,27 @@ impl Build {
7172
pub fn try_from_opts(build_opts: BuildOptions) -> Result<Self, Error> {
7273
let crate_path = set_crate_path(build_opts.path);
7374
let crate_name = manifest::get_crate_name(&crate_path)?;
75+
let mode = match build_opts.mode.as_str() {
76+
"no-install" => BuildMode::Noinstall,
77+
"normal" => BuildMode::Normal,
78+
_ => BuildMode::Normal,
79+
};
7480
// let build_config = manifest::xxx(&crate_path).xxx();
7581
Ok(Build {
7682
crate_path,
7783
scope: build_opts.scope,
7884
disable_dts: build_opts.disable_dts,
7985
target: build_opts.target,
8086
debug: build_opts.debug,
87+
mode,
8188
// build_config,
8289
crate_name,
8390
})
8491
}
8592

8693
/// Execute this `Build` command.
87-
pub fn run(&mut self, log: &Logger, mode: &BuildMode) -> Result<(), Error> {
88-
let process_steps = Build::get_process_steps(mode);
94+
pub fn run(&mut self, log: &Logger) -> Result<(), Error> {
95+
let process_steps = Build::get_process_steps(&self.mode);
8996

9097
let mut step_counter = Step::new(process_steps.len());
9198

@@ -213,8 +220,19 @@ impl Build {
213220
}
214221

215222
fn step_install_wasm_bindgen(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
223+
info!(&log, "Identifying WASM-bindgen dependency...");
224+
let bindgen_version = manifest::get_wasm_bindgen_version(&self.crate_path)?;
216225
info!(&log, "Installing wasm-bindgen-cli...");
217-
bindgen::cargo_install_wasm_bindgen(step)?;
226+
let install_permitted = match self.mode {
227+
BuildMode::Normal => true,
228+
BuildMode::Noinstall => false,
229+
};
230+
bindgen::cargo_install_wasm_bindgen(
231+
&self.crate_path,
232+
&bindgen_version,
233+
install_permitted,
234+
step,
235+
)?;
218236
info!(&log, "Installing wasm-bindgen-cli was successful.");
219237

220238
info!(&log, "Getting the crate name from the manifest...");

src/command/mod.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ mod pack;
66
mod publish;
77
pub mod utils;
88

9-
use self::build::{Build, BuildMode, BuildOptions};
9+
use self::build::{Build, BuildOptions};
1010
use self::login::login;
1111
use self::pack::pack;
1212
use self::publish::publish;
@@ -79,12 +79,7 @@ pub fn run_wasm_pack(command: Command, log: &Logger) -> result::Result<(), Error
7979
let status = match command {
8080
Command::Build(build_opts) => {
8181
info!(&log, "Running build command...");
82-
let build_mode = match build_opts.mode.as_str() {
83-
"no-install" => BuildMode::Noinstall,
84-
"normal" => BuildMode::Normal,
85-
_ => BuildMode::Normal,
86-
};
87-
Build::try_from_opts(build_opts).and_then(|mut b| b.run(&log, &build_mode))
82+
Build::try_from_opts(build_opts).and_then(|mut b| b.run(&log))
8883
}
8984
Command::Pack { path } => {
9085
info!(&log, "Running pack command...");

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ extern crate slog;
1919
extern crate slog_async;
2020
extern crate slog_term;
2121
extern crate toml;
22+
extern crate which;
2223

2324
pub mod bindgen;
2425
pub mod build;

src/manifest.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ fn check_wasm_bindgen(path: &Path) -> Result<(), Error> {
199199
"Ensure that you have \"{}\" as a dependency in your Cargo.toml file:\n[dependencies]\nwasm-bindgen = \"0.2\"",
200200
style("wasm-bindgen").bold().dim()
201201
))
202+
// FIXUP: Use the `get_wasm_bindgen_version` function for this?
203+
// let _ = get_wasm_bindgen_version(path)?;
204+
// Ok(())
202205
}
203206

204207
fn check_crate_type(path: &Path) -> Result<(), Error> {
@@ -212,3 +215,29 @@ fn check_crate_type(path: &Path) -> Result<(), Error> {
212215
"crate-type must be cdylib to compile to wasm32-unknown-unknown. Add the following to your Cargo.toml file:\n\n[lib]\ncrate-type = [\"cdylib\"]"
213216
)
214217
}
218+
219+
/// Get the version of `wasm-bindgen` specified as a dependency.
220+
pub fn get_wasm_bindgen_version(path: &Path) -> Result<String, Error> {
221+
if let Some(deps) = read_cargo_toml(path)?.dependencies {
222+
match deps.get("wasm_bindgen") {
223+
Some(CargoDependency::Simple(version)) => Ok(version.clone()),
224+
Some(CargoDependency::Detailed(_)) => {
225+
// FIXUP? Is this correct?
226+
let msg = format!(
227+
"\"{}\" dependency is missing its version number",
228+
style("wasm-bindgen").bold().dim()
229+
);
230+
Err(Error::CrateConfig { message: msg })
231+
}
232+
None => {
233+
let message = format!(
234+
"Ensure that you have \"{}\" as a dependency in your Cargo.toml file:\n[dependencies]\nwasm-bindgen = \"0.2\"",
235+
style("wasm-bindgen").bold().dim());
236+
Err(Error::CrateConfig { message })
237+
}
238+
}
239+
} else {
240+
let message = String::from("Could not find crate dependencies");
241+
Err(Error::CrateConfig { message })
242+
}
243+
}

0 commit comments

Comments
 (0)