3
3
use emoji;
4
4
use error:: Error ;
5
5
use progressbar:: Step ;
6
- use std:: path:: Path ;
6
+ use std:: path:: { Path , PathBuf } ;
7
7
use std:: process:: Command ;
8
+ use which:: which;
8
9
use PBAR ;
9
10
10
11
/// 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
+
12
39
let msg = format ! ( "{}Installing WASM-bindgen..." , emoji:: DOWN_ARROW ) ;
13
40
PBAR . step ( step, & msg) ;
14
41
let output = Command :: new ( "cargo" )
15
42
. arg ( "install" )
16
- . arg ( "wasm-bindgen-cli" )
17
43
. arg ( "--force" )
44
+ . arg ( "wasm-bindgen-cli" )
45
+ . arg ( "--version" )
46
+ . arg ( version)
47
+ . arg ( "--root" )
48
+ . arg ( path)
18
49
. output ( ) ?;
19
50
if !output. status . success ( ) {
51
+ let message = "Installing wasm-bindgen failed" . to_string ( ) ;
20
52
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
+ } )
26
57
} else {
27
58
Ok ( ( ) )
28
59
}
@@ -42,33 +73,88 @@ pub fn wasm_bindgen_build(
42
73
PBAR . step ( step, & msg) ;
43
74
let binary_name = name. replace ( "-" , "_" ) ;
44
75
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
- } ;
54
76
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
+ }
59
110
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" ) ;
69
122
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
71
136
} 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
73
159
}
74
160
}
0 commit comments