Merge branch 'master' into esm-type-and-main-in-package-json

master
Gunnlaugur Þór Briem 1 year ago
commit 473dbf8fae
  1. 11
      .github/workflows/book.yml
  2. 8
      .github/workflows/release.yml
  3. 11
      .github/workflows/test.yml
  4. 2
      .gitignore
  5. 368
      CHANGELOG.md
  6. 2713
      Cargo.lock
  7. 75
      Cargo.toml
  8. 2
      README.md
  9. 78
      docs/_installer/index.html
  10. 23
      docs/_installer/init.sh
  11. 18
      docs/_installer/wasm-pack.js
  12. 6
      docs/index.html
  13. 11
      docs/public/custom.css
  14. 4
      docs/src/cargo-toml-configuration.md
  15. 10
      docs/src/commands/build.md
  16. 4
      docs/src/contributing.md
  17. 2
      docs/src/prerequisites/considerations.md
  18. 2
      docs/src/prerequisites/non-rustup-setups.md
  19. 2
      docs/src/prerequisites/npm.md
  20. 2
      docs/src/tutorials/npm-browser-packages/getting-started/manual-setup.md
  21. 2
      docs/src/tutorials/npm-browser-packages/packaging-and-publishing.md
  22. 2
      npm/README.md
  23. 17
      npm/binary.js
  24. 383
      npm/package-lock.json
  25. 9
      npm/package.json
  26. 0
      npm/run.js
  27. 4
      npm/uninstall.js
  28. 152
      npm/yarn.lock
  29. 47
      src/bindgen.rs
  30. 24
      src/build/mod.rs
  31. 70
      src/build/wasm_target.rs
  32. 3
      src/cache.rs
  33. 10
      src/child.rs
  34. 144
      src/command/build.rs
  35. 17
      src/command/generate.rs
  36. 15
      src/command/login.rs
  37. 59
      src/command/mod.rs
  38. 13
      src/command/pack.rs
  39. 6
      src/command/publish/access.rs
  40. 21
      src/command/publish/mod.rs
  41. 79
      src/command/test.rs
  42. 10
      src/command/utils.rs
  43. 14
      src/generate.rs
  44. 41
      src/install/arch.rs
  45. 16
      src/install/krate.rs
  46. 90
      src/install/mod.rs
  47. 5
      src/install/mode.rs
  48. 41
      src/install/os.rs
  49. 12
      src/installer.rs
  50. 27
      src/lib.rs
  51. 22
      src/license.rs
  52. 18
      src/lockfile.rs
  53. 16
      src/main.rs
  54. 169
      src/manifest/mod.rs
  55. 2
      src/manifest/npm/commonjs.rs
  56. 4
      src/manifest/npm/esmodules.rs
  57. 2
      src/manifest/npm/nomodules.rs
  58. 25
      src/npm.rs
  59. 7
      src/progressbar.rs
  60. 13
      src/readme.rs
  61. 24
      src/stamps.rs
  62. 2
      src/target.rs
  63. 6
      src/test/mod.rs
  64. 21
      src/test/webdriver.rs
  65. 43
      src/test/webdriver/chromedriver.rs
  66. 72
      src/test/webdriver/geckodriver.rs
  67. 3
      src/test/webdriver/safaridriver.rs
  68. 55
      src/wasm_opt.rs
  69. 32
      tests/all/build.rs
  70. 69
      tests/all/download.rs
  71. 2
      tests/all/generate.rs
  72. 4
      tests/all/license.rs
  73. 2
      tests/all/lockfile.rs
  74. 29
      tests/all/log_level.rs
  75. 7
      tests/all/main.rs
  76. 23
      tests/all/manifest.rs
  77. 94
      tests/all/readme.rs
  78. 5
      tests/all/test.rs
  79. 4
      tests/all/utils/file.rs
  80. 9
      tests/all/utils/fixture.rs
  81. 14
      tests/all/utils/manifest.rs
  82. 2
      tests/all/wasm_opt.rs
  83. 3
      tests/all/webdriver.rs

@ -9,14 +9,13 @@ jobs:
name: Build and deploy book
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
override: true
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
env:
cache-name: cache-mdbook
with:
@ -31,7 +30,7 @@ jobs:
- name: Install mdbook
run: |
(test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
(test -x $HOME/.cargo/bin/mdbook || cargo install --vers "^0.3" mdbook)
(test -x $HOME/.cargo/bin/mdbook || cargo install --vers "^0.4" mdbook)
cargo install-update -a
- name: Build book
@ -42,7 +41,7 @@ jobs:
./build-installer
- name: Deploy book
uses: JamesIves/github-pages-deploy-action@4.1.4
uses: JamesIves/github-pages-deploy-action@v4.4.1
if: ${{ github.ref == 'refs/heads/master' }}
with:
branch: gh-pages

@ -38,12 +38,11 @@ jobs:
rust: stable
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.rust }}
override: true
target: wasm32-unknown-unknown
targets: wasm32-unknown-unknown
- name: Query version number
id: get_version
@ -96,6 +95,7 @@ jobs:
mv wasm-pack-init.exe ${{ env.RELEASE_DIR }}
- name: Create tarball
shell: bash
run: 7z a -ttar -so -an ./${{ env.RELEASE_DIR }}/${{ env.RELEASE_BIN }}-${{ steps.get_version.outputs.VERSION }}-${{ matrix.target }} | 7z a -si ./${{ env.RELEASE_DIR }}/${{ env.RELEASE_BIN }}-${{ steps.get_version.outputs.VERSION }}-${{ matrix.target }}.tar.gz
- name: Upload Zip

@ -28,17 +28,16 @@ jobs:
rust: stable
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: nanasess/setup-chromedriver@master
- uses: actions-rs/toolchain@v1
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.rust }}
override: true
target: wasm32-unknown-unknown
targets: wasm32-unknown-unknown
- uses: actions/setup-node@v2
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
env:
cache-name: cache-dependencies
with:
@ -52,7 +51,7 @@ jobs:
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('Cargo.lock') }}
- name: Run Tests
run: cargo test --features "strict" --all --locked
run: cargo test --all --locked
env:
RUST_BACKTRACE: 1

2
.gitignore vendored

@ -5,3 +5,5 @@ tests/bin
/build-installer
docs/book
docs/installer
.idea

@ -2,6 +2,374 @@
## 🤍 Unreleased
## ☀ 0.12.1
- ### 🤕 Fixes
- **Restore --version command - [lynn], [issue/1301], [pull/1305]**
The --version command got lost in space in v0.12.0. It's now brought back!
[issue/1301]: https://github.com/rustwasm/wasm-pack/issues/1301
[pull/1305]: https://github.com/rustwasm/wasm-pack/pull/1305
[lynn]: https://github.com/lynn
- **Fix value parser for Option<PathBuf> - [Myriad-Dreamin], [issue/1304], [pull/1307]**
A value parser for OsString cannot parse a command line argument for Option<PathBuf>,
which let it failed to specify paths for pack, publish and test commands, this faulty behavior
was introduced in v0.12.0.
[issue/1304]: https://github.com/rustwasm/wasm-pack/issues/1304
[pull/1307]: https://github.com/rustwasm/wasm-pack/pull/1307
[Myriad-Dreamin]: https://github.com/Myriad-Dreamin
## ☀ 0.12.0
- ### ✨ Features
- **Add --no-pack flag to build command - [hamza1311], [ashleygwilliams], [issue/691], [issue/811], [pull/695], [pull/1291]**
When calling wasm-pack build a user can optionally pass --no-pack and wasm-pack will build your wasm, generate js, and not build a package.json.
[issue/691]: https://github.com/rustwasm/wasm-pack/issues/691
[issue/811]: https://github.com/rustwasm/wasm-pack/issues/811
[pull/695]: https://github.com/rustwasm/wasm-pack/pull/695
[pull/1291]: https://github.com/rustwasm/wasm-pack/pull/1291
[ashleygwilliams]: https://github.com/ashleygwilliams
- **Add wasmbindgen option: omit_default_module_path - [matthiasgeihs], [pull/1272]**
Adds an option to call wasm-bindgen with --omit_default_module_path.
[pull/1272]: https://github.com/rustwasm/wasm-pack/pull/1272
[matthiasgeihs]: https://github.com/matthiasgeihs
- ### 🤕 Fixes
- **Add HTTP header USER-AGENT - [LeviticusNelson], [issue/1266], [pull/1285]**
We encountered some issues when we didn't send an User-Agent. This is now fixed.
[issue/1266]: https://github.com/rustwasm/wasm-pack/issues/1266
[pull/1285]: https://github.com/rustwasm/wasm-pack/pull/1285
[LeviticusNelson]: https://github.com/LeviticusNelson
- **Replace curl with ureq - [hamza1311], [issue/650], [issue/823], [issue/997], [issue/1079], [issue/1203], [issue/1234], [issue/1281], [pull/1290]**
The HTTP client is now pure Rust. Removes the dependency of openssl which have caused a lot of issues for people using wasm-pack on various distributions.
[issue/650]: https://github.com/rustwasm/wasm-pack/issues/650
[issue/823]: https://github.com/rustwasm/wasm-pack/issues/823
[issue/997]: https://github.com/rustwasm/wasm-pack/issues/997
[issue/1079]: https://github.com/rustwasm/wasm-pack/issues/1079
[issue/1203]: https://github.com/rustwasm/wasm-pack/issues/1203
[issue/1234]: https://github.com/rustwasm/wasm-pack/issues/1234
[issue/1281]: https://github.com/rustwasm/wasm-pack/issues/1281
[pull/1290]: https://github.com/rustwasm/wasm-pack/pull/1290
[hamza1311]: https://github.com/hamza1311
- **Update binary-install to 0.2.0. binary-install replaced curl with ureq - [drager]**
See [PR](https://github.com/rustwasm/binary-install/pull/24) in binary-install repo for more information.
[drager]: https://github.com/drager
- **Remove --always-auth from npm login - [EstebanBorai], [pull/1288]**
npm login doesn't support --always-auth anymore, instead it is under the adduser subcommand.
[pull/1288]: https://github.com/rustwasm/wasm-pack/pull/1288
[EstebanBorai]: https://github.com/EstebanBorai
- **Turn off cargo colors during log level test - [dtolnay], [pull/1294]**
[pull/1294]: https://github.com/rustwasm/wasm-pack/pull/1294
[dtolnay]: https://github.com/dtolnay
- **Fix getting the target-dir in wasm_bindgen_build - [tomasol], [issue/1278], [pull/1279]**
Fixes a wasm-pack panic if --target-dir was supplied (and arguments are not sorted).
[issue/1278]: https://github.com/rustwasm/wasm-pack/issues/1278
[pull/1279]: https://github.com/rustwasm/wasm-pack/pull/1279
[tomasol]: https://github.com/tomasol
- **Respect package.readme in Cargo.toml - [heaths], [issue/1215], [pull/1298], [pull/1216]**
wasm-pack now respects specifying readme=false:
```toml
[package]
readme = false
```
[issue/1215]: https://github.com/rustwasm/wasm-pack/issues/1215
[pull/1298]: https://github.com/rustwasm/wasm-pack/pull/1298
[pull/1216]: https://github.com/rustwasm/wasm-pack/pull/1216
[heaths]: https://github.com/heaths
- ### 📖 Documentation
- **Don't hide install options behind link - [oyamauchi], [issue/355], [pull/1242]**
[issue/355]: https://github.com/rustwasm/wasm-pack/issues/355
[pull/1242]: https://github.com/rustwasm/wasm-pack/issues/1242
[oyamauchi]: https://github.com/oyamauchi
- ### 🛠 Maintenance
- **Bump cargo-generate version to 0.18.2 - [sassman], [issue/1245] [pull/1269]**
[issue/1245]: https://github.com/rustwasm/wasm-pack/issues/1245
[pull/1269]: https://github.com/rustwasm/wasm-pack/pull/1269
[sassman]: https://github.com/sassman
- **Replace unmaintained actions-rs/toolchain action in CI workflows - [striezel], [pull/1246]**
Now we are using https://github.com/dtolnay/rust-toolchain instead.
[pull/1246]: https://github.com/rustwasm/wasm-pack/pull/1246
[striezel]: https://github.com/striezel
- **Update several dependencies - [hamza1311], [pull/1292]**
Updated clap, toml, predicates and serial_test to their latest versions.
[pull/1292]: https://github.com/rustwasm/wasm-pack/pull/1292
## 🌦 0.11.1
- ### 🤕 Fixes
- **Fix discovery of locally installed `wasm-opt` - [Liamolucko], [issue/1247], [pull/1257]**
[issue/1247]: https://github.com/rustwasm/wasm-pack/issues/1247
[pull/1257]: https://github.com/rustwasm/wasm-pack/pull/1257
[Liamolucko]: https://github.com/Liamolucko
- **Fix wasm-pack bin script entry - [ahippler], [issue/1248], [pull/1250]**
[issue/1248]: https://github.com/rustwasm/wasm-pack/issues/1248
[pull/1250]: https://github.com/rustwasm/wasm-pack/pull/1250
[ahippler]: https://github.com/ahippler
- ### 🛠 Maintenance
- **bump openssl from 0.10.46 to 0.10.48 - [pull/1254]**
[pull/1254]: https://github.com/rustwasm/wasm-pack/pull/1254
## 🌦 0.11.0
- ### ✨ Features
- **Make Deno target available - [egfx-notifications], [issue/672], [issue/879], [pull/1117]**
[issue/672]: https://github.com/rustwasm/wasm-pack/issues/672
[issue/879]: https://github.com/rustwasm/wasm-pack/issues/879
[pull/1117]: https://github.com/rustwasm/wasm-pack/pull/1117
[egfx-notifications]: https://github.com/egfx-notifications
- **Add support for more platforms to installer script - [omninonsense], [issue/1064], [issue/952], [issue/1125], [pull/1122]**
This makes the installation script work on M1 macs, as well as inside docker (especially when combined with buildx) for aarch64/arm64 architectures.
[issue/1064]: https://github.com/rustwasm/wasm-pack/issues/1064
[issue/952]: https://github.com/rustwasm/wasm-pack/issues/952
[issue/1125]: https://github.com/rustwasm/wasm-pack/issues/1125
[pull/1122]: https://github.com/rustwasm/wasm-pack/pull/1122
[omninonsense]: https://github.com/omninonsense
- **Add Linux arm64 support - [nnelgxorz], [issue/1169], [pull/1170]**
[issue/1169]: https://github.com/rustwasm/wasm-pack/issues/1169
[pull/1170]: https://github.com/rustwasm/wasm-pack/pull/1170
[nnelgxorz]: https://github.com/nnelgxorz
- **Add support for workspace inheritance - [printfn], [issue/1180], [pull/1185]**
[issue/1180]: https://github.com/rustwasm/wasm-pack/issues/1180
[pull/1185]: https://github.com/rustwasm/wasm-pack/pull/1185
- ### 🤕 Fixes
- **--target-dir as extra option is now considered as expected - [sassman], [issue/1076], [pull/1082]**
[issue/1076]: https://github.com/rustwasm/wasm-pack/issues/1076
[pull/1082]: https://github.com/rustwasm/wasm-pack/pull/1082
[sassman]: https://github.com/sassman
- **Pass through --weak-refs --reference-types flags to bindgen - [serprex], [issue/930], [pull/937]**
[issue/930]: https://github.com/rustwasm/wasm-pack/issues/930
[pull/937]: https://github.com/rustwasm/wasm-pack/pull/937
[serprex]: https://github.com/serprex
- **Fix binaryen URL and use updated binary-install to fix installation on macOS - [matheus23], [printfn], [pull/1188]**
Use the updated binary-install crate (rustwasm/binary-install#21), switches from failure to anyhow to match what binary-install uses, and fixes wasm-opt installation on macOS.
[pull/1188]: https://github.com/rustwasm/wasm-pack/pull/1188
[matheus23]: https://github.com/matheus23
[printfn]: https://github.com/printfn
[rustwasm/binary-install#21]: https://github.com/rustwasm/binary-install/pull/21
- **Mark snippets and the bundler target's main file as having side effects - [Liamolucko], [issue/972], [rustwasm/wasm-bindgen/3276], [pull/1224]**
[issue/972]: https://github.com/rustwasm/wasm-pack/issues/972
[rustwasm/wasm-bindgen/3276]: https://github.com/rustwasm/wasm-bindgen/issues/3276
[pull/1224]: https://github.com/rustwasm/wasm-pack/pull/1224
[Liamolucko]: https://github.com/Liamolucko
- ### 📖 Documentation
- **Fix typos in non-rustup-setups.md - [dallasbrittany], [issue/1141], [pull/1142]**
[issue/1141]: https://github.com/rustwasm/wasm-pack/issues/1141
[pull/1142]: https://github.com/rustwasm/wasm-pack/issues/1141
[dallasbrittany]: https://github.com/dallasbrittany
- **Fix typos in considerations.md - [lhjt], [pull/1066]**
[pull/1066]: https://github.com/rustwasm/wasm-pack/pull/1066
[lhjt]: https://github.com/lhjt
- **Grammar and typo fixes - [helixbass], [pull/1143]**
[pull/1143]: https://github.com/rustwasm/wasm-pack/pull/1143
[helixbass]: https://github.com/helixbass
- **Replace two mentions of wasm-pack init with wasm-pack build in the docs - [mstange], [pull/1086]**
[pull/1086]: https://github.com/rustwasm/wasm-pack/pull/1086
[mstange]: https://github.com/mstange
- **Update npm installation link - [benediktwerner], [pull/1227]**
[pull/1227]: https://github.com/rustwasm/wasm-pack/pull/1227
[benediktwerner]: https://github.com/benediktwerner
- ### 🛠 Maintenance
- **Bump wasm-opt to version 108 - [MichaelMauderer], [issue/1135] [pull/1136]**
[pull/1136]: https://github.com/rustwasm/wasm-pack/pull/1136
[issue/1135]: https://github.com/rustwasm/wasm-pack/issues/1135
[MichaelMauderer]: https://github.com/MichaelMauderer
- **Update binary-install to v1.0.1 - [EverlastingBugstopper], [pull/1130]**
[pull/1130]: https://github.com/rustwasm/wasm-pack/pull/1130
- **Add back run.js to npm installer - [EverlastingBugstopper], [pull/1149]**
[pull/1149]: https://github.com/rustwasm/wasm-pack/pull/1149
- **Fix some typos in the codebase - [striezel], [pull/1220]**
[pull/1220]: https://github.com/rustwasm/wasm-pack/pull/1220
[striezel]: https://github.com/striezel
- **Update actions/checkout in GitHub Actions workflows to v3 - [striezel], [pull/1221]**
[pull/1221]: https://github.com/rustwasm/wasm-pack/pull/1221
- **Update actions/cache in GitHub Actions workflows to v3 - [striezel], [pull/1222]**
[pull/1222]: https://github.com/rustwasm/wasm-pack/pull/1222
- **Update JamesIves/github-pages-deploy-action in GHA workflow to v4.4.1 - [striezel], [pull/1223]**
[pull/1223]: https://github.com/rustwasm/wasm-pack/pull/1223
## 🌦 0.10.3
- ### 🤕 Fixes
- **Use bash to create release tarballs - [nasso], [issue/1097] [pull/1144]**
Fixes Windows installer failure due to malformatted tar.
[pull/1144]: https://github.com/rustwasm/wasm-pack/pull/1144
[issue/1097]: https://github.com/rustwasm/wasm-pack/issues/1097
[nasso]: https://github.com/nasso
- **Clean up package.json from previous runs - [main--], [issue/1110-comment] [pull/1119]**
Remove the package.json file from previous runs to avoid crashes.
[pull/1119]: https://github.com/rustwasm/wasm-pack/pull/1119
[issue/1110-comment]: https://github.com/rustwasm/wasm-pack/pull/1110#issuecomment-1059008962
[main--]: https://github.com/main--
- **Do not remove the pkg directory - [huntc], [issue/1099] [pull/1110]**
A recent change ensured that the pkg directory was removed as the first step of attempting to create it.
Unfortunately, this caused a problem for webpack when watching the pkg directory.
Webpack was unable to recover its watching and so any watch server must be restarted,
which is a blocker when using it. This PR and release fixes this.
[pull/1110]: https://github.com/rustwasm/wasm-pack/pull/1110
[issue/1099]: https://github.com/rustwasm/wasm-pack/issues/1099
[huntc]: https://github.com/huntc
- **Bump regex from 1.5.4 to 1.5.6 - [dependabot], [pull/1147]**
Version 1.5.5 of the regex crate fixed a security bug in the regex compiler.
[pull/1147]: https://github.com/rustwasm/wasm-pack/pull/1147
- **Bump openssl-src from 111.17.0+1.1.1m to 111.20.0+1.1.1o - [dependabot], [pull/1146]**
Bring in bug fixes from the new version of openssl-src.
[pull/1146]: https://github.com/rustwasm/wasm-pack/pull/1146
[dependabot]: https://github.com/apps/dependabot
## 🌦 0.10.2
- ### ✨ Features
- **Implement support for RFC 8, transitive NPM dependencies - [jpgneves], [issue/606] [pull/986]**
[pull/986]: https://github.com/rustwasm/wasm-pack/pull/986
[issue/606]: https://github.com/rustwasm/wasm-pack/issues/606
[jpgneves]: https://github.com/jpgneves
- ### 🤕 Fixes
- **Add support for macos aarch64 - [d3lm], [issue/913] [pull/1088]**
This fixes aarch64 for MacOS and will download x86_64-apple-darwin.
[pull/1088]: https://github.com/rustwasm/wasm-pack/pull/1088
[issue/913]: https://github.com/rustwasm/wasm-pack/issues/913
[d3lm]: https://github.com/d3lm
- **Add linux/arm64 to release workflow - [nacardin], [issue/1064] [pull/1065]**
[pull/1065]: https://github.com/rustwasm/wasm-pack/pull/1065
[issue/1064]: https://github.com/rustwasm/wasm-pack/issues/1064
[nacardin]: https://github.com/nacardin
- **Force axios version - [drager], [pull/1094]**
Forces npm package `axios` to version `0.21.2` in order to get security fix for a security vulnerability present in axios
before version `0.21.2`.
[pull/1094]: https://github.com/rustwasm/wasm-pack/pull/1094
- ### 📖 Documentation
- **Update docs for how to pass extra options to cargo - [FrankenApps], [issue/1059] [pull/1073]**
[FrankenApps]: https://github.com/FrankenApps
[pull/1073]: https://github.com/rustwasm/wasm-pack/pull/1073
[issue/1059]: https://github.com/rustwasm/wasm-pack/issues/1059
## 🌦 0.10.1
- ### 🤕 Fixes

2713
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -1,56 +1,45 @@
[package]
name = "wasm-pack"
description = "📦✨ your favorite rust -> wasm workflow tool!"
version = "0.10.1"
version = "0.12.1"
authors = ["Ashley Williams <ashley666ashley@gmail.com>", "Jesper Håkansson <jesper@jesperh.se>"]
repository = "https://github.com/rustwasm/wasm-pack.git"
license = "MIT/Apache-2.0"
license = "MIT OR Apache-2.0"
edition = "2021"
readme = "README.md"
categories = ["wasm"]
documentation = "https://rustwasm.github.io/wasm-pack/"
[dependencies]
atty = "0.2.11"
cargo_metadata = "0.8.0"
console = "0.6.1"
dialoguer = "0.3.0"
curl = "0.4.13"
env_logger = { version = "0.5.13", default-features = false }
failure = "0.1.2"
human-panic = "1.0.1"
glob = "0.2"
log = "0.4.6"
openssl = { version = '0.10.11', optional = true }
parking_lot = "0.6"
reqwest = "0.9.14"
semver = "0.9.0"
serde = "1.0.74"
serde_derive = "1.0.74"
serde_ignored = "0.0.4"
serde_json = "1.0.26"
strsim = "0.8.0"
siphasher = "0.2.3"
structopt = "0.3"
toml = "0.4"
which = "2.0.0"
binary-install = "0.0.2"
walkdir = "2"
chrono = "0.4.6"
anyhow = "1.0.68"
atty = "0.2.14"
binary-install = "0.2.0"
cargo_metadata = "0.15.2"
chrono = "0.4.23"
console = "0.15.5"
dialoguer = "0.10.3"
env_logger = { version = "0.10.0", default-features = false }
glob = "0.3.1"
human-panic = "1.0.3"
log = "0.4.17"
parking_lot = "0.12.1"
semver = "1.0.16"
serde = "1.0.152"
serde_derive = "1.0.152"
serde_ignored = "0.1.7"
serde_json = "1.0.91"
siphasher = "0.3.10"
strsim = "0.10.0"
clap = { version = "4.2.5", features = ["derive"] }
toml = "0.7.3"
ureq = { version = "2.6.2", features = ["json"] }
walkdir = "2.3.2"
which = "4.4.0"
[dev-dependencies]
assert_cmd = "0.11"
lazy_static = "1.1.0"
predicates = "1.0.0"
serial_test = "0.3"
tempfile = "3"
assert_cmd = "2.0.8"
lazy_static = "1.4.0"
predicates = "3.0.3"
serial_test = "2.0.0"
tempfile = "3.3.0"
[features]
# OpenSSL is vendored by default, can use system OpenSSL through feature flag.
default = ['openssl/vendored']
# Treat compiler warnings as a build error.
# This only runs in CI by default
strict = ['openssl/vendored']
sys-openssl = ['openssl']
# Keeping feature for users already using this feature flag
vendored-openssl = ['openssl/vendored']

@ -85,7 +85,7 @@ check out our [contribution policy].
This project is part of the [rustwasm Working Group].
This project was started by [ashleygwilliams] and is co-maintained by [ashleygwilliams], [drager] and the Rust Wasm Working Group Core Team.
This project was started by [ashleygwilliams] and is maintained by [drager] and the Rust Wasm Working Group Core Team.
[ashleygwilliams]: https://github.com/ashleygwilliams
[drager]: https://github.com/drager

@ -5,10 +5,6 @@
<link href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css" rel="stylesheet">
<link rel="stylesheet" href="../public/custom.css"/>
<style>
.instructions {
padding: 100px;
border: 1px solid #eee;
}
.winlink {
display: block;
}
@ -29,7 +25,7 @@
<a href="/wasm-pack">
<img src="../public/img/rustwasm.png">
</a>
</a>
</li>
<li class="navbar-item">
<a href="https://github.com/rustwasm/wasm-pack/issues/new/choose">File an Issue</a>
</li>
@ -47,37 +43,33 @@
<h1>Install <code>wasm-pack</code></h1>
<div class="container">
<div id="platform-instructions-unix" style="display: none;">
<div class="curl">
<code>curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh</code>
<p>
You appear to be running a *nix system (Unix, Linux, MacOS). If not,
<a class="default-platform-button" href="#">display all supported installers</a>.
You appear to be running a *nix system (Unix, Linux, MacOS).
Install by running:
</p>
<pre class="primary">curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh</pre>
<p>
If you're not on *nix, or you don't like installing from <b>curl</b>,
follow the alternate instructions below.
</p>
</div>
</div>
<div id="platform-instructions-win64" class="instructions" style="display: none;">
<div id="platform-instructions-win64" style="display: none;">
<p>
You appear to be running Windows 64-bit, download and run
<a class='winlink' href="https://github.com/rustwasm/wasm-pack/releases/download/$VERSION/wasm-pack-init.exe">wasm-pack-init.exe</a>
You appear to be running Windows 64-bit. Download and run
<a class="winlink" href="https://github.com/rustwasm/wasm-pack/releases/download/$VERSION/wasm-pack-init.exe">wasm-pack-init.exe</a>
then follow the onscreen instructions.
</p>
<hr/>
<p>
If you're a Windows Subsystem for Linux user run the following in your
If you're a Windows Subsystem for Linux user, run the following in your
terminal, then follow the onscreen instructions to install wasm-pack.
</p>
<code>curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh</code>
<hr/>
<p>
You appear to be running Windows 64-bit. If not,
<a class="default-platform-button" href="#">
display all supported installers
</a>.
</p>
<pre class="primary">curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh</pre>
<p>If you're not on Windows 64-bit, follow the alternate instructions below.</p>
</div>
<div id="platform-instructions-unknown" class="instructions" style="display: none;">
<div id="platform-instructions-unknown" style="display: none;">
<p>I don't recognize your platform.</p>
<p>
We would appreciate it if you
@ -92,43 +84,17 @@
</div>
</div>
<div id="platform-instructions-default" class="instructions">
<div>
<p>
To install wasm-pack, if you are running a *nix system (Unix, Linux, MacOS),<br/>
run the following in your terminal, then follow the onscreen
instructions.
</p>
<code>curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh</code>
</div>
<hr/>
<div>
<p>
If you are running Windows 64-bit,<br/>download and run
<a class='winlink' href="https://github.com/rustwasm/wasm-pack/releases/download/$VERSION/wasm-pack-init.exe">wasm-pack-init.exe</a>
then follow the onscreen instructions.
</p>
</div>
<hr/>
<div>
<hr />
<div id="generic-instructions">
<p>
For all other platforms, run the following in your terminal:
To install from source on any platform:
</p>
<code>cargo install wasm-pack</code>
</div>
<hr/>
<div>
<p><code>cargo install wasm-pack</code></p>
<p>
Install using <b>npm</b> or <b>yarn</b>:
On supported platforms, you can also use <b>npm</b> or <b>yarn</b> to download a precompiled binary:
</p>
<code>
npm install -g wasm-pack
</code>
or
<code>
yarn global add wasm-pack
</code>
</div>
<p><code>npm install -g wasm-pack</code> or <code>yarn global add wasm-pack</code></p>
</div>
</div>
</section>

@ -85,6 +85,19 @@ get_architecture() {
local _ostype="$(uname -s)"
local _cputype="$(uname -m)"
# This is when installing inside docker, or can be useful to side-step
# the script's built-in platform detection heuristic (if it drifts again in the future)
set +u
if [ -n "$TARGETOS" ]; then
_ostype="$TARGETOS" # probably always linux
fi
if [ -n "$TARGETARCH" ]; then
_cputype="$TARGETARCH"
fi
set -u
if [ "$_ostype" = Darwin -a "$_cputype" = i386 ]; then
# Darwin `uname -s` lies
if sysctl hw.optional.x86_64 | grep -q ': 1'; then
@ -93,7 +106,7 @@ get_architecture() {
fi
case "$_ostype" in
Linux)
Linux | linux)
local _ostype=unknown-linux-musl
;;
@ -114,11 +127,19 @@ get_architecture() {
x86_64 | x86-64 | x64 | amd64)
local _cputype=x86_64
;;
arm64 | aarch64)
local _cputype=aarch64
;;
*)
err "no precompiled binaries available for CPU architecture: $_cputype"
esac
# See https://github.com/rustwasm/wasm-pack/pull/1088
if [ "$_cputype" == "aarch64" ] && [ "$_ostype" == "apple-darwin" ]; then
_cputype="x86_64"
fi
local _arch="$_cputype-$_ostype"
RETVAL="$_arch"

@ -1,4 +1,4 @@
var platforms = ["default", "unknown", "win64", "unix"];
var platforms = ["unknown", "win64", "unix"];
var platform_override = null;
function detect_platform() {
@ -59,25 +59,12 @@ function adjust_for_platform() {
platforms.forEach(function (platform_elem) {
var platform_div = document.getElementById("platform-instructions-" + platform_elem);
platform_div.style.display = "none";
if (platform == platform_elem ||
(platform == 'unknown' && platform_elem == 'default')) {
if (platform === platform_elem) {
platform_div.style.display = "block";
}
});
}
function go_to_default_platform() {
platform_override = 0;
adjust_for_platform();
}
function set_up_default_platform_buttons() {
var defaults_buttons = document.getElementsByClassName('default-platform-button');
for (var i = 0; i < defaults_buttons.length; i++) {
defaults_buttons[i].onclick = go_to_default_platform;
}
}
function fill_in_bug_report_values() {
var nav_plat = document.getElementById("nav-plat");
var nav_app = document.getElementById("nav-app");
@ -87,6 +74,5 @@ function fill_in_bug_report_values() {
(function () {
adjust_for_platform();
set_up_default_platform_buttons();
fill_in_bug_report_values();
}());

@ -42,9 +42,9 @@
<h2>📦✨ your favorite rust -> wasm workflow tool!</h2>
</div>
<div class="five columns" id="installer">
<a class="button button-primary" href="/wasm-pack/installer">✨ Install wasm-pack 0.10.1 ✨</a>
<p>5 Sep 2021 |
<a href="https://github.com/rustwasm/wasm-pack/releases/tag/v0.10.1">
<a class="button button-primary" href="/wasm-pack/installer">✨ Install wasm-pack 0.12.1 ✨</a>
<p>27 June 2023 |
<a href="https://github.com/rustwasm/wasm-pack/releases/tag/v0.12.1">
Release Notes
</a>
</p>

@ -79,15 +79,10 @@
width: 20%;
}
.curl {
padding: 50px;
}
.curl p {
margin-top: 50px;
}
pre.primary {
margin: 0 auto 2.5rem auto;
width: fit-content;
.curl code {
padding: 20px;
font-size: 2rem;
background-color: #000;

@ -27,6 +27,8 @@ debug-js-glue = true
demangle-name-section = true
# Should we emit the DWARF debug info custom sections?
dwarf-debug-info = false
# Should we omit the default import path?
omit-default-module-path = false
[package.metadata.wasm-pack.profile.profiling]
wasm-opt = ['-O']
@ -35,6 +37,7 @@ wasm-opt = ['-O']
debug-js-glue = false
demangle-name-section = true
dwarf-debug-info = false
omit-default-module-path = false
# `wasm-opt` is on by default in for the release profile, but it can be
# disabled by setting it to `false`
@ -45,4 +48,5 @@ wasm-opt = false
debug-js-glue = false
demangle-name-section = true
dwarf-debug-info = false
omit-default-module-path = false
```

@ -1,6 +1,6 @@
# wasm-pack build
The `wasm-pack build` command creates the files neccessary for JavaScript
The `wasm-pack build` command creates the files necessary for JavaScript
interoperability and for publishing a package to npm. This involves compiling
your code to wasm and generating a pkg folder. This pkg folder will contain the
wasm binary, a JS wrapper file, your `README`, and a `package.json` file.
@ -22,7 +22,7 @@ path is given, the `build` command will run in the current directory.
## Output Directory
By default, `wasm-pack` will generate a directory for it's build output called `pkg`.
By default, `wasm-pack` will generate a directory for its build output called `pkg`.
If you'd like to customize this you can use the `--out-dir` flag.
```
@ -99,7 +99,7 @@ wasm-pack build --target nodejs
## Scope
The init command also accepts an optional `--scope` argument. This will scope
The `build` command also accepts an optional `--scope` argument. This will scope
your package name, which is useful if your package name might conflict with
something in the public registry. For example:
@ -122,7 +122,7 @@ wasm-pack build examples/js-hello-world --mode no-install
| Option | Description |
|---------------|------------------------------------------------------------------------------------------|
| `no-install` | `wasm-pack init` implicitly and create wasm binding without installing `wasm-bindgen`. |
| `no-install` | `wasm-pack build` implicitly and create wasm binding without installing `wasm-bindgen`. |
| `normal` | do all the stuffs of `no-install` with installed `wasm-bindgen`. |
## Extra options
@ -133,7 +133,7 @@ at the very end of your command, just as you would for `cargo build`. For
example, to build the previous example using cargo's offline feature:
```
wasm-pack build examples/js-hello-world --mode no-install --offline
wasm-pack build examples/js-hello-world --mode no-install -- --offline
```
<hr style="font-size: 1.5em; margin-top: 2.5em"/>

@ -12,14 +12,14 @@ You'll also want to check out the contributing [guidelines].
## 🏃 Up and Running
1. fork and clone this repository
1. fork and clone the `rustwasm/wasm-pack` repository
2. install [node/npm]
2. `cd wasm-pack`
3. `cargo run`. To test command line arguments you can run `cargo run -- <args>`.
## Documentation
Documentation lives in the `/docs` directory. Each command has it's own page.
Documentation lives in the `/docs` directory. Each command has its own page.
Additionally there are extra pages explaining the prerequisites, setup, and how to
contribute (which you are reading now!).

@ -14,7 +14,7 @@ ReqwestError(reqwest::Error { kind: Builder, source: "JsValue(ReferenceError: Re
ReferenceError: Response is not defined
```
## Workarround
## Workaround
Import or declare fetch and objects: Headers, Request, Response
```ts

@ -1,5 +1,5 @@
# Non-Rustup setups
`wasm-pack` compiles your code using the `wasm32-unknown-unknown` target. `wasm-pack` will automatically add this target for Rustup setups if you don't already have it installed by doing `rustup target add wasm32-unknown-unknown`. However, if you're not using Rustup we won't be able to this automatically and you'll have to do this yourself.
`wasm-pack` compiles your code using the `wasm32-unknown-unknown` target. `wasm-pack` will automatically add this target for Rustup setups if you don't already have it installed by doing `rustup target add wasm32-unknown-unknown`. However, if you're not using Rustup, then we won't be able to do this automatically, and you'll have to do this yourself.
## Manually add wasm32-unknown-unknown
*Disclaimer: This is not guaranteed to work for every setup. These instructions below are specific for setups that match the exact rustc release, which means that the downloaded wasm32 target can be incompatible.*

@ -21,5 +21,5 @@ your package to the npm registry you'll need an npm account.
You can find information about signing up for npm [here][npm-signup-info].
[`npm link`]: https://docs.npmjs.com/cli/link
[npm-install-info]: https://www.npmjs.com/get-npm
[npm-install-info]: https://docs.npmjs.com/downloading-and-installing-node-js-and-npm
[npm-signup-info]: https://www.npmjs.com/signup

@ -44,7 +44,7 @@ name = "hello-wasm"
version = "0.1.0"
authors = ["Ashley Williams <ashley666ashley@gmail.com>"]
description = "babby's first wasm package"
license = "MIT/Apache-2.0"
license = "MIT OR Apache-2.0"
repository = "https://github.com/ashleygwilliams/hello-wasm"
[lib]

@ -7,7 +7,7 @@ command:
$ wasm-pack build --scope MYSCOPE
```
where `MYSCOPE` is your npm username. Normally you could just type `wasm-pack init` but since
where `MYSCOPE` is your npm username. Normally you could just type `wasm-pack build` but since
other people are doing this tutorial as well we don't want conflicts with the `wasm-add` package
name! This command when run does a few things:

@ -85,7 +85,7 @@ check out our [contribution policy].
This project is part of the [rustwasm Working Group].
This project was started by [ashleygwilliams] and is co-maintained by [ashleygwilliams], [drager] and the Rust Wasm Working Group Core Team.
This project was started by [ashleygwilliams] and is maintained by [drager] and the Rust Wasm Working Group Core Team.
[ashleygwilliams]: https://github.com/ashleygwilliams
[drager]: https://github.com/drager

@ -13,7 +13,10 @@ const getPlatform = () => {
if (type === "Linux" && arch === "x64") {
return "x86_64-unknown-linux-musl";
}
if (type === "Darwin" && arch === "x64") {
if (type === "Linux" && arch === "arm64") {
return "aarch64-unknown-linux-musl";
}
if (type === "Darwin" && (arch === "x64" || arch === "arm64")) {
return "x86_64-apple-darwin";
}
@ -29,23 +32,17 @@ const getBinary = () => {
return new Binary(platform === windows ? "wasm-pack.exe" : "wasm-pack", url);
};
const run = () => {
const binary = getBinary();
binary.run();
};
const install = () => {
const binary = getBinary();
binary.install();
};
const uninstall = () => {
const run = () => {
const binary = getBinary();
binary.uninstall();
};
binary.run();
}
module.exports = {
install,
run,
uninstall,
};

383
npm/package-lock.json generated

@ -1,383 +0,0 @@
{
"name": "wasm-pack",
"version": "0.10.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "wasm-pack",
"version": "0.10.1",
"hasInstallScript": true,
"license": "MIT OR Apache-2.0",
"dependencies": {
"binary-install": "^0.1.0"
},
"bin": {
"wasm-pack": "run.js"
}
},
"node_modules/axios": {
"version": "0.21.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
"integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
"dependencies": {
"follow-redirects": "^1.10.0"
}
},
"node_modules/balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"node_modules/binary-install": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/binary-install/-/binary-install-0.1.1.tgz",
"integrity": "sha512-DqED0D/6LrS+BHDkKn34vhRqOGjy5gTMgvYZsGK2TpNbdPuz4h+MRlNgGv5QBRd7pWq/jylM4eKNCizgAq3kNQ==",
"dependencies": {
"axios": "^0.21.1",
"rimraf": "^3.0.2",
"tar": "^6.1.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
"engines": {
"node": ">=10"
}
},
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"node_modules/follow-redirects": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz",
"integrity": "sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA==",
"engines": {
"node": ">=4.0"
}
},
"node_modules/fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"dependencies": {
"minipass": "^3.0.0"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"node_modules/glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
}
},
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/minipass": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz",
"integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==",
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/minizlib": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
"dependencies": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"bin": {
"mkdirp": "bin/cmd.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dependencies": {
"glob": "^7.1.3"
},
"bin": {
"rimraf": "bin.js"
}
},
"node_modules/tar": {
"version": "6.1.11",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
"integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
"dependencies": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
"minipass": "^3.0.0",
"minizlib": "^2.1.1",
"mkdirp": "^1.0.3",
"yallist": "^4.0.0"
},
"engines": {
"node": ">= 10"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
},
"dependencies": {
"axios": {
"version": "0.21.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
"integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
"requires": {
"follow-redirects": "^1.10.0"
}
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"binary-install": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/binary-install/-/binary-install-0.1.1.tgz",
"integrity": "sha512-DqED0D/6LrS+BHDkKn34vhRqOGjy5gTMgvYZsGK2TpNbdPuz4h+MRlNgGv5QBRd7pWq/jylM4eKNCizgAq3kNQ==",
"requires": {
"axios": "^0.21.1",
"rimraf": "^3.0.2",
"tar": "^6.1.0"
}
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"follow-redirects": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz",
"integrity": "sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA=="
},
"fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"requires": {
"minipass": "^3.0.0"
}
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minipass": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz",
"integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==",
"requires": {
"yallist": "^4.0.0"
}
},
"minizlib": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
"requires": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
}
},
"mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"requires": {
"wrappy": "1"
}
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
},
"rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"requires": {
"glob": "^7.1.3"
}
},
"tar": {
"version": "6.1.11",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
"integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
"requires": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
"minipass": "^3.0.0",
"minizlib": "^2.1.1",
"mkdirp": "^1.0.3",
"yallist": "^4.0.0"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
}
}

@ -1,11 +1,10 @@
{
"name": "wasm-pack",
"version": "0.10.1",
"version": "0.12.1",
"description": "📦✨ your favorite rust -> wasm workflow tool!",
"main": "binary.js",
"scripts": {
"postinstall": "node ./install.js",
"preuninstall": "node ./uninstall.js"
"postinstall": "node ./install.js"
},
"bin": {
"wasm-pack": "./run.js"
@ -23,13 +22,13 @@
"npm",
"package"
],
"author": "Ashley Williams <ashley666ashley@gmail.com>",
"author": "Jesper Håkansson <jesper@jesperh.se>",
"license": "MIT OR Apache-2.0",
"bugs": {
"url": "https://github.com/rustwasm/wasm-pack/issues"
},
"homepage": "https://github.com/rustwasm/wasm-pack#readme",
"dependencies": {
"binary-install": "^0.1.0"
"binary-install": "^1.0.1"
}
}

@ -1,4 +0,0 @@
#!/usr/bin/env node
const { uninstall } = require("./binary");
uninstall();

@ -0,0 +1,152 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
axios@^0.26.1:
version "0.26.1"
resolved "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz"
integrity sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==
dependencies:
follow-redirects "^1.14.8"
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
binary-install@^1.0.1:
version "1.0.6"
resolved "https://registry.yarnpkg.com/binary-install/-/binary-install-1.0.6.tgz#7d603003da4f890d13d3e887773e86776e0d24a3"
integrity sha512-h3K4jaC4jEauK3csXI9GxGBJldkpuJlHCIBv8i+XBNhPuxnlERnD1PWVczQYDqvhJfv0IHUbB3lhDrZUMHvSgw==
dependencies:
axios "^0.26.1"
rimraf "^3.0.2"
tar "^6.1.11"
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz"
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
chownr@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz"
integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
follow-redirects@^1.14.8:
version "1.14.9"
resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz"
integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==
fs-minipass@^2.0.0:
version "2.1.0"
resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz"
integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==
dependencies:
minipass "^3.0.0"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
glob@^7.1.3:
version "7.2.0"
resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz"
integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz"
integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
dependencies:
once "^1.3.0"
wrappy "1"
inherits@2:
version "2.0.4"
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
minimatch@^3.0.4:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"
minipass@^3.0.0:
version "3.1.6"
resolved "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz"
integrity sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==
dependencies:
yallist "^4.0.0"
minizlib@^2.1.1:
version "2.1.2"
resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz"
integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==
dependencies:
minipass "^3.0.0"
yallist "^4.0.0"
mkdirp@^1.0.3:
version "1.0.4"
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
once@^1.3.0:
version "1.4.0"
resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz"
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
dependencies:
wrappy "1"
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
rimraf@^3.0.2:
version "3.0.2"
resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz"
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
dependencies:
glob "^7.1.3"
tar@^6.1.11:
version "6.1.11"
resolved "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz"
integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==
dependencies:
chownr "^2.0.0"
fs-minipass "^2.0.0"
minipass "^3.0.0"
minizlib "^2.1.1"
mkdirp "^1.0.3"
yallist "^4.0.0"
wrappy@1:
version "1.0.2"
resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==

@ -1,10 +1,10 @@
//! Functionality related to running `wasm-bindgen`.
use child;
use command::build::{BuildProfile, Target};
use failure::{self, ResultExt};
use install::{self, Tool};
use manifest::CrateData;
use crate::child;
use crate::command::build::{BuildProfile, Target};
use crate::install::{self, Tool};
use crate::manifest::CrateData;
use anyhow::{bail, Context, Result};
use semver;
use std::path::Path;
use std::process::Command;
@ -17,9 +17,12 @@ pub fn wasm_bindgen_build(
out_dir: &Path,
out_name: &Option<String>,
disable_dts: bool,
weak_refs: bool,
reference_types: bool,
target: Target,
profile: BuildProfile,
) -> Result<(), failure::Error> {
extra_options: &Vec<String>,
) -> Result<()> {
let release_or_debug = match profile {
BuildProfile::Release | BuildProfile::Profiling => "release",
BuildProfile::Dev => "debug",
@ -27,8 +30,16 @@ pub fn wasm_bindgen_build(
let out_dir = out_dir.to_str().unwrap();
let wasm_path = data
.target_directory()
let target_directory = {
let mut has_target_dir_iter = extra_options.iter();
has_target_dir_iter
.find(|&it| it == "--target-dir")
.and_then(|_| has_target_dir_iter.next())
.map(Path::new)
.unwrap_or(data.target_directory())
};
let wasm_path = target_directory
.join("wasm32-unknown-unknown")
.join(release_or_debug)
.join(data.crate_name())
@ -48,6 +59,14 @@ pub fn wasm_bindgen_build(
.arg(out_dir)
.arg(dts_arg);
if weak_refs {
cmd.arg("--weak-refs");
}
if reference_types {
cmd.arg("--reference-types");
}
let target_arg = build_target_arg(target, &bindgen_path)?;
if supports_dash_dash_target(&bindgen_path)? {
cmd.arg("--target").arg(target_arg);
@ -69,13 +88,16 @@ pub fn wasm_bindgen_build(
if profile.wasm_bindgen_dwarf_debug_info() {
cmd.arg("--keep-debug");
}
if profile.wasm_bindgen_omit_default_module_path() {
cmd.arg("--omit-default-module-path");
}
child::run(cmd, "wasm-bindgen").context("Running the wasm-bindgen CLI")?;
Ok(())
}
/// Check if the `wasm-bindgen` dependency is locally satisfied for the web target
fn supports_web_target(cli_path: &Path) -> Result<bool, failure::Error> {
fn supports_web_target(cli_path: &Path) -> Result<bool> {
let cli_version = semver::Version::parse(&install::get_cli_version(
&install::Tool::WasmBindgen,
cli_path,
@ -85,7 +107,7 @@ fn supports_web_target(cli_path: &Path) -> Result<bool, failure::Error> {
}
/// Check if the `wasm-bindgen` dependency is locally satisfied for the --target flag
fn supports_dash_dash_target(cli_path: &Path) -> Result<bool, failure::Error> {
fn supports_dash_dash_target(cli_path: &Path) -> Result<bool> {
let cli_version = semver::Version::parse(&install::get_cli_version(
&install::Tool::WasmBindgen,
cli_path,
@ -94,7 +116,7 @@ fn supports_dash_dash_target(cli_path: &Path) -> Result<bool, failure::Error> {
Ok(cli_version >= expected_version)
}
fn build_target_arg(target: Target, cli_path: &Path) -> Result<String, failure::Error> {
fn build_target_arg(target: Target, cli_path: &Path) -> Result<String> {
if !supports_dash_dash_target(cli_path)? {
Ok(build_target_arg_legacy(target, cli_path)?)
} else {
@ -102,7 +124,7 @@ fn build_target_arg(target: Target, cli_path: &Path) -> Result<String, failure::
}
}
fn build_target_arg_legacy(target: Target, cli_path: &Path) -> Result<String, failure::Error> {
fn build_target_arg_legacy(target: Target, cli_path: &Path) -> Result<String> {
log::info!("Your version of wasm-bindgen is out of date. You should consider updating your Cargo.toml to a version >= 0.2.40.");
let target_arg = match target {
Target::Nodejs => "--nodejs",
@ -115,6 +137,7 @@ fn build_target_arg_legacy(target: Target, cli_path: &Path) -> Result<String, fa
}
}
Target::Bundler => "--browser",
Target::Deno => "--deno",
};
Ok(target_arg.to_string())
}

@ -1,14 +1,14 @@
//! Building a Rust crate into a `.wasm` binary.
use child;
use command::build::BuildProfile;
use emoji;
use failure::{Error, ResultExt};
use manifest::Crate;
use crate::child;
use crate::command::build::BuildProfile;
use crate::emoji;
use crate::manifest::Crate;
use crate::PBAR;
use anyhow::{bail, Context, Result};
use std::path::Path;
use std::process::Command;
use std::str;
use PBAR;
pub mod wasm_target;
@ -23,7 +23,7 @@ pub struct WasmPackVersion {
}
/// Ensure that `rustc` is present and that it is >= 1.30.0
pub fn check_rustc_version() -> Result<String, Error> {
pub fn check_rustc_version() -> Result<String> {
let local_minor_version = rustc_minor_version();
match local_minor_version {
Some(mv) => {
@ -60,7 +60,7 @@ fn rustc_minor_version() -> Option<u32> {
}
/// Checks and returns local and latest versions of wasm-pack
pub fn check_wasm_pack_versions() -> Result<WasmPackVersion, Error> {
pub fn check_wasm_pack_versions() -> Result<WasmPackVersion> {
match wasm_pack_local_version() {
Some(local) => Ok(WasmPackVersion {local, latest: Crate::return_wasm_pack_latest_version()?.unwrap_or_else(|| "".to_string())}),
None => bail!("We can't figure out what your wasm-pack version is, make sure the installation path is correct.")
@ -77,7 +77,7 @@ pub fn cargo_build_wasm(
path: &Path,
profile: BuildProfile,
extra_options: &[String],
) -> Result<(), Error> {
) -> Result<()> {
let msg = format!("{}Compiling to Wasm...", emoji::CYCLONE);
PBAR.info(&msg);
@ -125,11 +125,7 @@ pub fn cargo_build_wasm(
/// * `path`: Path to the crate directory to build tests.
/// * `debug`: Whether to build tests in `debug` mode.
/// * `extra_options`: Additional parameters to pass to `cargo` when building tests.
pub fn cargo_build_wasm_tests(
path: &Path,
debug: bool,
extra_options: &[String],
) -> Result<(), Error> {
pub fn cargo_build_wasm_tests(path: &Path, debug: bool, extra_options: &[String]) -> Result<()> {
let mut cmd = Command::new("cargo");
cmd.current_dir(path).arg("build").arg("--tests");

@ -1,13 +1,14 @@
//! Checking for the wasm32 target
use child;
use emoji;
use failure::{Error, ResultExt};
use crate::child;
use crate::emoji;
use crate::PBAR;
use anyhow::{anyhow, bail, Context, Result};
use log::error;
use log::info;
use std::fmt;
use std::path::{Path, PathBuf};
use std::path::PathBuf;
use std::process::Command;
use PBAR;
struct Wasm32Check {
rustc_path: PathBuf,
@ -52,7 +53,7 @@ impl fmt::Display for Wasm32Check {
/// Ensure that `rustup` has the `wasm32-unknown-unknown` target installed for
/// current toolchain
pub fn check_for_wasm32_target() -> Result<(), Error> {
pub fn check_for_wasm32_target() -> Result<()> {
let msg = format!("{}Checking for the Wasm target...", emoji::TARGET);
PBAR.info(&msg);
@ -65,7 +66,7 @@ pub fn check_for_wasm32_target() -> Result<(), Error> {
}
/// Get rustc's sysroot as a PathBuf
fn get_rustc_sysroot() -> Result<PathBuf, Error> {
fn get_rustc_sysroot() -> Result<PathBuf> {
let command = Command::new("rustc")
.args(&["--print", "sysroot"])
.output()?;
@ -73,36 +74,65 @@ fn get_rustc_sysroot() -> Result<PathBuf, Error> {
if command.status.success() {
Ok(String::from_utf8(command.stdout)?.trim().into())
} else {
Err(format_err!(
Err(anyhow!(
"Getting rustc's sysroot wasn't successful. Got {}",
command.status
))
}
}
/// Checks if the wasm32-unknown-unknown is present in rustc's sysroot.
fn is_wasm32_target_in_sysroot(sysroot: &Path) -> bool {
let wasm32_target = "wasm32-unknown-unknown";
/// Get wasm32-unknown-unknown target libdir
fn get_rustc_wasm32_unknown_unknown_target_libdir() -> Result<PathBuf> {
let command = Command::new("rustc")
.args(&[
"--target",
"wasm32-unknown-unknown",
"--print",
"target-libdir",
])
.output()?;
let rustlib_path = sysroot.join("lib/rustlib");
if command.status.success() {
Ok(String::from_utf8(command.stdout)?.trim().into())
} else {
Err(anyhow!(
"Getting rustc's wasm32-unknown-unknown target wasn't successful. Got {}",
command.status
))
}
}
info!("Looking for {} in {:?}", wasm32_target, rustlib_path);
fn does_wasm32_target_libdir_exist() -> bool {
let result = get_rustc_wasm32_unknown_unknown_target_libdir();
if rustlib_path.join(wasm32_target).exists() {
info!("Found {} in {:?}", wasm32_target, rustlib_path);
match result {
Ok(wasm32_target_libdir_path) => {
if wasm32_target_libdir_path.exists() {
info!(
"Found wasm32-unknown-unknown in {:?}",
wasm32_target_libdir_path
);
true
} else {
info!("Failed to find {} in {:?}", wasm32_target, rustlib_path);
info!(
"Failed to find wasm32-unknown-unknown in {:?}",
wasm32_target_libdir_path
);
false
}
}
Err(_) => {
error!("Some error in getting the target libdir!");
false
}
}
}
fn check_wasm32_target() -> Result<Wasm32Check, Error> {
fn check_wasm32_target() -> Result<Wasm32Check> {
let sysroot = get_rustc_sysroot()?;
let rustc_path = which::which("rustc")?;
// If wasm32-unknown-unknown already exists we're ok.
if is_wasm32_target_in_sysroot(&sysroot) {
if does_wasm32_target_libdir_exist() {
Ok(Wasm32Check {
rustc_path,
sysroot,
@ -132,7 +162,7 @@ fn check_wasm32_target() -> Result<Wasm32Check, Error> {
}
/// Add wasm32-unknown-unknown using `rustup`.
fn rustup_add_wasm_target() -> Result<(), Error> {
fn rustup_add_wasm_target() -> Result<()> {
let mut cmd = Command::new("rustup");
cmd.arg("target").arg("add").arg("wasm32-unknown-unknown");
child::run(cmd, "rustup").context("Adding the wasm32-unknown-unknown target with rustup")?;

@ -1,11 +1,12 @@
//! Getting and configuring wasm-pack's binary cache.
use anyhow::Result;
use binary_install::Cache;
use std::env;
use std::path::Path;
/// Get wasm-pack's binary cache.
pub fn get_wasm_pack_cache() -> Result<Cache, failure::Error> {
pub fn get_wasm_pack_cache() -> Result<Cache> {
if let Ok(path) = env::var("WASM_PACK_CACHE") {
Ok(Cache::at(Path::new(&path)))
} else {

@ -1,10 +1,10 @@
//! Utilties for managing child processes.
//! Utilities for managing child processes.
//!
//! This module helps us ensure that all child processes that we spawn get
//! properly logged and their output is logged as well.
use failure::Error;
use install::Tool;
use crate::install::Tool;
use anyhow::{bail, Result};
use log::info;
use std::process::{Command, Stdio};
@ -25,7 +25,7 @@ pub fn new_command(program: &str) -> Command {
}
/// Run the given command and return on success.
pub fn run(mut command: Command, command_name: &str) -> Result<(), Error> {
pub fn run(mut command: Command, command_name: &str) -> Result<()> {
info!("Running {:?}", command);
let status = command.status()?;
@ -43,7 +43,7 @@ pub fn run(mut command: Command, command_name: &str) -> Result<(), Error> {
}
/// Run the given command and return its stdout.
pub fn run_capture_stdout(mut command: Command, command_name: &Tool) -> Result<String, Error> {
pub fn run_capture_stdout(mut command: Command, command_name: &Tool) -> Result<String> {
info!("Running {:?}", command);
let output = command

@ -1,25 +1,25 @@
//! Implementation of the `wasm-pack build` command.
use crate::bindgen;
use crate::build;
use crate::cache;
use crate::command::utils::{create_pkg_dir, get_crate_path};
use crate::emoji;
use crate::install::{self, InstallMode, Tool};
use crate::license;
use crate::lockfile::Lockfile;
use crate::manifest;
use crate::readme;
use crate::wasm_opt;
use crate::PBAR;
use anyhow::{anyhow, bail, Error, Result};
use binary_install::Cache;
use bindgen;
use build;
use cache;
use command::utils::{create_pkg_dir, get_crate_path};
use emoji;
use failure::Error;
use install::{self, InstallMode, Tool};
use license;
use lockfile::Lockfile;
use clap::Args;
use log::info;
use manifest;
use readme;
use std::fmt;
use std::path::PathBuf;
use std::str::FromStr;
use std::time::Instant;
use structopt::clap::AppSettings;
use PBAR;
/// Everything required to configure and run the `wasm-pack build` command.
#[allow(missing_docs)]
@ -28,7 +28,10 @@ pub struct Build {
pub crate_data: manifest::CrateData,
pub scope: Option<String>,
pub disable_dts: bool,
pub weak_refs: bool,
pub reference_types: bool,
pub target: Target,
pub no_pack: bool,
pub profile: BuildProfile,
pub mode: InstallMode,
pub out_dir: PathBuf,
@ -55,6 +58,9 @@ pub enum Target {
/// in a browser but pollutes the global namespace and must be manually
/// instantiated.
NoModules,
/// Correspond to `--target deno` where the output is natively usable as
/// a Deno module loaded with `import`.
Deno,
}
impl Default for Target {
@ -70,6 +76,7 @@ impl fmt::Display for Target {
Target::Web => "web",
Target::Nodejs => "nodejs",
Target::NoModules => "no-modules",
Target::Deno => "deno",
};
write!(f, "{}", s)
}
@ -77,12 +84,13 @@ impl fmt::Display for Target {
impl FromStr for Target {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Error> {
fn from_str(s: &str) -> Result<Self> {
match s {
"bundler" | "browser" => Ok(Target::Bundler),
"web" => Ok(Target::Web),
"nodejs" => Ok(Target::Nodejs),
"no-modules" => Ok(Target::NoModules),
"deno" => Ok(Target::Deno),
_ => bail!("Unknown target: {}", s),
}
}
@ -101,62 +109,67 @@ pub enum BuildProfile {
}
/// Everything required to configure and run the `wasm-pack build` command.
#[derive(Debug, StructOpt)]
#[structopt(
// Allows unknown `--option`s to be parsed as positional arguments, so we can forward it to `cargo`.
setting = AppSettings::AllowLeadingHyphen,
// Allows `--` to be parsed as an argument, so we can forward it to `cargo`.
setting = AppSettings::TrailingVarArg,
)]
#[derive(Debug, Args)]
#[command(allow_hyphen_values = true, trailing_var_arg = true)]
pub struct BuildOptions {
/// The path to the Rust crate. If not set, searches up the path from the current directory.
#[structopt(parse(from_os_str))]
#[clap()]
pub path: Option<PathBuf>,
/// The npm scope to use in package.json, if any.
#[structopt(long = "scope", short = "s")]
#[clap(long = "scope", short = 's')]
pub scope: Option<String>,
#[structopt(long = "mode", short = "m", default_value = "normal")]
#[clap(long = "mode", short = 'm', default_value = "normal")]
/// Sets steps to be run. [possible values: no-install, normal, force]
pub mode: InstallMode,
#[structopt(long = "no-typescript")]
#[clap(long = "no-typescript")]
/// By default a *.d.ts file is generated for the generated JS file, but
/// this flag will disable generating this TypeScript file.
pub disable_dts: bool,
#[structopt(long = "target", short = "t", default_value = "bundler")]
#[clap(long = "weak-refs")]
/// Enable usage of the JS weak references proposal.
pub weak_refs: bool,
#[clap(long = "reference-types")]
/// Enable usage of WebAssembly reference types.
pub reference_types: bool,
#[clap(long = "target", short = 't', default_value = "bundler")]
/// Sets the target environment. [possible values: bundler, nodejs, web, no-modules]
pub target: Target,
#[structopt(long = "debug")]
#[clap(long = "debug")]
/// Deprecated. Renamed to `--dev`.
pub debug: bool,
#[structopt(long = "dev")]
#[clap(long = "dev")]
/// Create a development build. Enable debug info, and disable
/// optimizations.
pub dev: bool,
#[structopt(long = "release")]
#[clap(long = "release")]
/// Create a release build. Enable optimizations and disable debug info.
pub release: bool,
#[structopt(long = "profiling")]
#[clap(long = "profiling")]
/// Create a profiling build. Enable optimizations and debug info.
pub profiling: bool,
#[structopt(long = "out-dir", short = "d", default_value = "pkg")]
#[clap(long = "out-dir", short = 'd', default_value = "pkg")]
/// Sets the output directory with a relative path.
pub out_dir: String,
#[structopt(long = "out-name")]
#[clap(long = "out-name")]
/// Sets the output file names. Defaults to package name.
pub out_name: Option<String>,
#[structopt(allow_hyphen_values = true)]
#[clap(long = "no-pack", alias = "no-package")]
/// Option to not generate a package.json
pub no_pack: bool,
/// List of extra options to pass to `cargo build`
pub extra_options: Vec<String>,
}
@ -168,9 +181,12 @@ impl Default for BuildOptions {
scope: None,
mode: InstallMode::default(),
disable_dts: false,
weak_refs: false,
reference_types: false,
target: Target::default(),
debug: false,
dev: false,
no_pack: false,
release: false,
profiling: false,
out_dir: String::new(),
@ -180,11 +196,11 @@ impl Default for BuildOptions {
}
}
type BuildStep = fn(&mut Build) -> Result<(), Error>;
type BuildStep = fn(&mut Build) -> Result<()>;
impl Build {
/// Construct a build command from the given options.
pub fn try_from_opts(mut build_opts: BuildOptions) -> Result<Self, Error> {
pub fn try_from_opts(mut build_opts: BuildOptions) -> Result<Self> {
if let Some(path) = &build_opts.path {
if path.to_string_lossy().starts_with("--") {
let path = build_opts.path.take().unwrap();
@ -202,7 +218,7 @@ impl Build {
(false, false, false) | (false, true, false) => BuildProfile::Release,
(true, false, false) => BuildProfile::Dev,
(false, false, true) => BuildProfile::Profiling,
// Unfortunately, `structopt` doesn't expose clap's `conflicts_with`
// Unfortunately, `clap` doesn't expose clap's `conflicts_with`
// functionality yet, so we have to implement it ourselves.
_ => bail!("Can only supply one of the --dev, --release, or --profiling flags"),
};
@ -212,7 +228,10 @@ impl Build {
crate_data,
scope: build_opts.scope,
disable_dts: build_opts.disable_dts,
weak_refs: build_opts.weak_refs,
reference_types: build_opts.reference_types,
target: build_opts.target,
no_pack: build_opts.no_pack,
profile,
mode: build_opts.mode,
out_dir,
@ -229,8 +248,8 @@ impl Build {
}
/// Execute this `Build` command.
pub fn run(&mut self) -> Result<(), Error> {
let process_steps = Build::get_process_steps(self.mode);
pub fn run(&mut self) -> Result<()> {
let process_steps = Build::get_process_steps(self.mode, self.no_pack);
let started = Instant::now();
@ -255,7 +274,7 @@ impl Build {
Ok(())
}
fn get_process_steps(mode: InstallMode) -> Vec<(&'static str, BuildStep)> {
fn get_process_steps(mode: InstallMode, no_pack: bool) -> Vec<(&'static str, BuildStep)> {
macro_rules! steps {
($($name:ident),+) => {
{
@ -277,20 +296,27 @@ impl Build {
]);
}
}
steps.extend(steps![
step_build_wasm,
step_create_dir,
step_copy_readme,
step_copy_license,
step_install_wasm_bindgen,
step_run_wasm_bindgen,
step_run_wasm_opt,
]);
if !no_pack {
steps.extend(steps![
step_create_json,
step_copy_readme,
step_copy_license,
]);
}
steps
}
fn step_check_rustc_version(&mut self) -> Result<(), Error> {
fn step_check_rustc_version(&mut self) -> Result<()> {
info!("Checking rustc version...");
let version = build::check_rustc_version()?;
let msg = format!("rustc version is {}.", version);
@ -298,21 +324,21 @@ impl Build {
Ok(())
}
fn step_check_crate_config(&mut self) -> Result<(), Error> {
fn step_check_crate_config(&mut self) -> Result<()> {
info!("Checking crate configuration...");
self.crate_data.check_crate_config()?;
info!("Crate is correctly configured.");
Ok(())
}
fn step_check_for_wasm_target(&mut self) -> Result<(), Error> {
fn step_check_for_wasm_target(&mut self) -> Result<()> {
info!("Checking for wasm-target...");
build::wasm_target::check_for_wasm32_target()?;
info!("Checking for wasm-target was successful.");
Ok(())
}
fn step_build_wasm(&mut self) -> Result<(), Error> {
fn step_build_wasm(&mut self) -> Result<()> {
info!("Building wasm...");
build::cargo_build_wasm(&self.crate_path, self.profile, &self.extra_options)?;
@ -327,14 +353,14 @@ impl Build {
Ok(())
}
fn step_create_dir(&mut self) -> Result<(), Error> {
fn step_create_dir(&mut self) -> Result<()> {
info!("Creating a pkg directory...");
create_pkg_dir(&self.out_dir)?;
info!("Created a pkg directory at {:#?}.", &self.crate_path);
Ok(())
}
fn step_create_json(&mut self) -> Result<(), Error> {
fn step_create_json(&mut self) -> Result<()> {
self.crate_data.write_package_json(
&self.out_dir,
&self.scope,
@ -348,21 +374,21 @@ impl Build {
Ok(())
}
fn step_copy_readme(&mut self) -> Result<(), Error> {
fn step_copy_readme(&mut self) -> Result<()> {
info!("Copying readme from crate...");
readme::copy_from_crate(&self.crate_path, &self.out_dir)?;
readme::copy_from_crate(&self.crate_data, &self.crate_path, &self.out_dir)?;
info!("Copied readme from crate to {:#?}.", &self.out_dir);
Ok(())
}
fn step_copy_license(&mut self) -> Result<(), failure::Error> {
fn step_copy_license(&mut self) -> Result<()> {
info!("Copying license from crate...");
license::copy_from_crate(&self.crate_data, &self.crate_path, &self.out_dir)?;
info!("Copied license from crate to {:#?}.", &self.out_dir);
Ok(())
}
fn step_install_wasm_bindgen(&mut self) -> Result<(), failure::Error> {
fn step_install_wasm_bindgen(&mut self) -> Result<()> {
info!("Identifying wasm-bindgen dependency...");
let lockfile = Lockfile::new(&self.crate_data)?;
let bindgen_version = lockfile.require_wasm_bindgen()?;
@ -378,7 +404,7 @@ impl Build {
Ok(())
}
fn step_run_wasm_bindgen(&mut self) -> Result<(), Error> {
fn step_run_wasm_bindgen(&mut self) -> Result<()> {
info!("Building the wasm bindings...");
bindgen::wasm_bindgen_build(
&self.crate_data,
@ -386,15 +412,18 @@ impl Build {
&self.out_dir,
&self.out_name,
self.disable_dts,
self.weak_refs,
self.reference_types,
self.target,
self.profile,
&self.extra_options,
)?;
info!("wasm bindings were built at {:#?}.", &self.out_dir);
Ok(())
}
fn step_run_wasm_opt(&mut self) -> Result<(), Error> {
let args = match self
fn step_run_wasm_opt(&mut self) -> Result<()> {
let mut args = match self
.crate_data
.configured_profile(self.profile)
.wasm_opt_args()
@ -402,6 +431,9 @@ impl Build {
Some(args) => args,
None => return Ok(()),
};
if self.reference_types {
args.push("--enable-reference-types".into());
}
info!("executing wasm-opt with {:?}", args);
wasm_opt::run(
&self.cache,
@ -409,7 +441,7 @@ impl Build {
&args,
self.mode.install_permitted(),
).map_err(|e| {
format_err!(
anyhow!(
"{}\nTo disable `wasm-opt`, add `wasm-opt = false` to your package metadata in your `Cargo.toml`.", e
)
})

@ -1,18 +1,13 @@
use cache;
use failure::Error;
use generate;
use install::{self, Tool};
use crate::cache;
use crate::generate;
use crate::install::{self, Tool};
use crate::PBAR;
use anyhow::Result;
use log::info;
use std::result;
use PBAR;
/// Executes the 'cargo-generate' command in the current directory
/// which generates a new rustwasm project from a template.
pub fn generate(
template: String,
name: String,
install_permitted: bool,
) -> result::Result<(), Error> {
pub fn generate(template: String, name: String, install_permitted: bool) -> Result<()> {
info!("Generating a new rustwasm project...");
let download = install::download_prebuilt_or_cargo_install(
Tool::CargoGenerate,

@ -1,23 +1,22 @@
use crate::npm;
use crate::PBAR;
use anyhow::Result;
use log::info;
use npm;
use std::result;
use PBAR;
pub fn login(
registry: Option<String>,
scope: &Option<String>,
always_auth: bool,
auth_type: &Option<String>,
) -> result::Result<(), failure::Error> {
) -> Result<()> {
let registry = registry.unwrap_or_else(|| npm::DEFAULT_NPM_REGISTRY.to_string());
info!("Logging in to npm...");
info!(
"Scope: {:?} Registry: {}, Always Auth: {}, Auth Type: {:?}.",
&scope, &registry, always_auth, &auth_type
"Scope: {:?} Registry: {}, Auth Type: {:?}.",
&scope, &registry, &auth_type
);
info!("npm info located in the npm debug log");
npm::npm_login(&registry, &scope, always_auth, &auth_type)?;
npm::npm_login(&registry, &scope, &auth_type)?;
info!("Logged you in!");
PBAR.info(&"👋 logged you in!".to_string());

@ -17,68 +17,66 @@ use self::pack::pack;
use self::publish::{access::Access, publish};
use self::test::{Test, TestOptions};
use crate::install::InstallMode;
use failure::Error;
use anyhow::Result;
use clap::Subcommand;
use log::info;
use std::path::PathBuf;
use std::result;
/// The various kinds of commands that `wasm-pack` can execute.
#[derive(Debug, StructOpt)]
#[derive(Debug, Subcommand)]
pub enum Command {
/// 🏗 build your npm package!
#[structopt(name = "build", alias = "init")]
#[clap(name = "build", alias = "init")]
Build(BuildOptions),
#[structopt(name = "pack")]
#[clap(name = "pack")]
/// 🍱 create a tar of your npm package but don't publish!
Pack {
/// The path to the Rust crate. If not set, searches up the path from the current dirctory.
#[structopt(parse(from_os_str))]
/// The path to the Rust crate. If not set, searches up the path from the current directory.
#[clap()]
path: Option<PathBuf>,
},
#[structopt(name = "new")]
#[clap(name = "new")]
/// 🐑 create a new project with a template
Generate {
/// The name of the project
name: String,
/// The URL to the template
#[structopt(
#[clap(
long = "template",
short = "temp",
default_value = "https://github.com/rustwasm/wasm-pack-template"
)]
template: String,
#[structopt(long = "mode", short = "m", default_value = "normal")]
#[clap(long = "mode", short = 'm', default_value = "normal")]
/// Should we install or check the presence of binary tools. [possible values: no-install, normal, force]
mode: InstallMode,
},
#[structopt(name = "publish")]
#[clap(name = "publish")]
/// 🎆 pack up your npm package and publish!
Publish {
#[structopt(long = "target", short = "t", default_value = "bundler")]
#[clap(long = "target", short = 't', default_value = "bundler")]
/// Sets the target environment. [possible values: bundler, nodejs, web, no-modules]
target: String,
/// The access level for the package to be published
#[structopt(long = "access", short = "a")]
#[clap(long = "access", short = 'a')]
access: Option<Access>,
/// The distribution tag being used for publishing.
/// See https://docs.npmjs.com/cli/dist-tag
#[structopt(long = "tag")]
#[clap(long = "tag")]
tag: Option<String>,
/// The path to the Rust crate. If not set, searches up the path from the current dirctory.
#[structopt(parse(from_os_str))]
/// The path to the Rust crate. If not set, searches up the path from the current directory.
#[clap()]
path: Option<PathBuf>,
},
#[structopt(name = "login", alias = "adduser", alias = "add-user")]
#[clap(name = "login", alias = "adduser", alias = "add-user")]
/// 👤 Add an npm registry user account! (aliases: adduser, add-user)
Login {
#[structopt(long = "registry", short = "r")]
#[clap(long = "registry", short = 'r')]
/// Default: 'https://registry.npmjs.org/'.
/// The base URL of the npm package registry. If scope is also
/// specified, this registry will only be used for packages with that
@ -86,19 +84,13 @@ pub enum Command {
/// currently in, if any.
registry: Option<String>,
#[structopt(long = "scope", short = "s")]
#[clap(long = "scope", short = 's')]
/// Default: none.
/// If specified, the user and login credentials given will be
/// associated with the specified scope.
scope: Option<String>,
#[structopt(long = "always-auth", short = "a")]
/// If specified, save configuration indicating that all requests to the
/// given registry should include authorization information. Useful for
/// private registries. Can be used with --registry and / or --scope
always_auth: bool,
#[structopt(long = "auth-type", short = "t")]
#[clap(long = "auth-type", short = 't')]
/// Default: 'legacy'.
/// Type: 'legacy', 'sso', 'saml', 'oauth'.
/// What authentication strategy to use with adduser/login. Some npm
@ -107,13 +99,13 @@ pub enum Command {
auth_type: Option<String>,
},
#[structopt(name = "test")]
#[clap(name = "test")]
/// 👩🔬 test your wasm!
Test(TestOptions),
}
/// Run a command with the given logger!
pub fn run_wasm_pack(command: Command) -> result::Result<(), Error> {
pub fn run_wasm_pack(command: Command) -> Result<()> {
// Run the correct command based off input and store the result of it so that we can clear
// the progress bar then return it
match command {
@ -149,15 +141,14 @@ pub fn run_wasm_pack(command: Command) -> result::Result<(), Error> {
Command::Login {
registry,
scope,
always_auth,
auth_type,
} => {
info!("Running login command...");
info!(
"Registry: {:?}, Scope: {:?}, Always Auth: {}, Auth Type: {:?}",
&registry, &scope, &always_auth, &auth_type
"Registry: {:?}, Scope: {:?}, Auth Type: {:?}",
&registry, &scope, &auth_type
);
login(registry, &scope, always_auth, &auth_type)
login(registry, &scope, &auth_type)
}
Command::Test(test_opts) => {
info!("Running test command...");

@ -1,19 +1,18 @@
use command::utils::{find_pkg_directory, get_crate_path};
use failure::Error;
use crate::command::utils::{find_pkg_directory, get_crate_path};
use crate::npm;
use crate::PBAR;
use anyhow::{anyhow, Result};
use log::info;
use npm;
use std::path::PathBuf;
use std::result;
use PBAR;
/// Executes the 'npm pack' command on the 'pkg' directory
/// which creates a tarball that can be published to the NPM registry
pub fn pack(path: Option<PathBuf>) -> result::Result<(), Error> {
pub fn pack(path: Option<PathBuf>) -> Result<()> {
let crate_path = get_crate_path(path)?;
info!("Packing up the npm package...");
let pkg_directory = find_pkg_directory(&crate_path).ok_or_else(|| {
format_err!(
anyhow!(
"Unable to find the pkg directory at path {:#?}, or in a child directory of {:#?}",
&crate_path,
&crate_path

@ -1,9 +1,9 @@
use failure::Error;
use anyhow::{bail, Error, Result};
use std::fmt;
use std::str::FromStr;
/// Represents access level for the to-be publish package. Passed to `wasm-pack publish` as a flag, e.g. `--access=public`.
#[derive(Debug)]
#[derive(Clone, Debug)]
pub enum Access {
/// Access is granted to all. All unscoped packages *must* be public.
Public,
@ -14,7 +14,7 @@ pub enum Access {
impl FromStr for Access {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Error> {
fn from_str(s: &str) -> Result<Self> {
match s {
"public" => Ok(Access::Public),
"restricted" => Ok(Access::Restricted),

@ -2,16 +2,15 @@
pub mod access;
use self::access::Access;
use command::build::{Build, BuildOptions, Target};
use command::utils::{find_pkg_directory, get_crate_path};
use dialoguer::{Confirmation, Input, Select};
use failure::Error;
use crate::command::build::{Build, BuildOptions, Target};
use crate::command::utils::{find_pkg_directory, get_crate_path};
use crate::npm;
use crate::PBAR;
use anyhow::{anyhow, bail, Result};
use dialoguer::{Confirm, Input, Select};
use log::info;
use npm;
use std::path::PathBuf;
use std::result;
use std::str::FromStr;
use PBAR;
/// Creates a tarball from a 'pkg' directory
/// and publishes it to the NPM registry
@ -20,7 +19,7 @@ pub fn publish(
path: Option<PathBuf>,
access: Option<Access>,
tag: Option<String>,
) -> result::Result<(), Error> {
) -> Result<()> {
let crate_path = get_crate_path(path)?;
info!("Publishing the npm package...");
@ -31,8 +30,8 @@ pub fn publish(
None => {
// while `wasm-pack publish`, if the pkg directory cannot be found,
// then try to `wasm-pack build`
if Confirmation::new()
.with_text("Your package hasn't been built, build it?")
if Confirm::new()
.with_prompt("Your package hasn't been built, build it?")
.interact()?
{
let out_dir = Input::new()
@ -58,7 +57,7 @@ pub fn publish(
.and_then(|mut build| build.run())
.map(|()| crate_path.join(out_dir))
.map_err(|_| {
format_err!(
anyhow!(
"Unable to find the pkg directory at path '{:#?}',\
or in a child directory of '{:#?}'",
&crate_path,

@ -1,91 +1,84 @@
//! Implementation of the `wasm-pack test` command.
use crate::build;
use crate::cache;
use crate::command::utils::get_crate_path;
use crate::install::{self, InstallMode, Tool};
use crate::lockfile::Lockfile;
use crate::manifest;
use crate::test::{self, webdriver};
use anyhow::{bail, Result};
use binary_install::Cache;
use build;
use cache;
use command::utils::get_crate_path;
use clap::Args;
use console::style;
use failure::Error;
use install::{self, InstallMode, Tool};
use lockfile::Lockfile;
use log::info;
use manifest;
use std::path::PathBuf;
use std::str::FromStr;
use std::time::Instant;
use structopt::clap::AppSettings;
use test::{self, webdriver};
#[derive(Debug, Default, StructOpt)]
#[structopt(
// Allows unknown `--option`s to be parsed as positional arguments, so we can forward it to `cargo`.
setting = AppSettings::AllowLeadingHyphen,
// Allows `--` to be parsed as an argument, so we can forward it to `cargo`.
setting = AppSettings::TrailingVarArg,
)]
#[derive(Debug, Default, Args)]
#[command(allow_hyphen_values = true, trailing_var_arg = true)]
/// Everything required to configure the `wasm-pack test` command.
pub struct TestOptions {
#[structopt(long = "node")]
#[clap(long = "node")]
/// Run the tests in Node.js.
pub node: bool,
#[structopt(long = "firefox")]
#[clap(long = "firefox")]
/// Run the tests in Firefox. This machine must have a Firefox installation.
/// If the `geckodriver` WebDriver client is not on the `$PATH`, and not
/// specified with `--geckodriver`, then `wasm-pack` will download a local
/// copy.
pub firefox: bool,
#[structopt(long = "geckodriver", parse(from_os_str))]
#[clap(long = "geckodriver")]
/// The path to the `geckodriver` WebDriver client for testing in
/// Firefox. Implies `--firefox`.
pub geckodriver: Option<PathBuf>,
#[structopt(long = "chrome")]
#[clap(long = "chrome")]
/// Run the tests in Chrome. This machine must have a Chrome installation.
/// If the `chromedriver` WebDriver client is not on the `$PATH`, and not
/// specified with `--chromedriver`, then `wasm-pack` will download a local
/// copy.
pub chrome: bool,
#[structopt(long = "chromedriver", parse(from_os_str))]
#[clap(long = "chromedriver")]
/// The path to the `chromedriver` WebDriver client for testing in
/// Chrome. Implies `--chrome`.
pub chromedriver: Option<PathBuf>,
#[structopt(long = "safari")]
#[clap(long = "safari")]
/// Run the tests in Safari. This machine must have a Safari installation,
/// and the `safaridriver` WebDriver client must either be on the `$PATH` or
/// specified explicitly with the `--safaridriver` flag. `wasm-pack` cannot
/// download the `safaridriver` WebDriver client for you.
pub safari: bool,
#[structopt(long = "safaridriver", parse(from_os_str))]
#[clap(long = "safaridriver")]
/// The path to the `safaridriver` WebDriver client for testing in
/// Safari. Implies `--safari`.
pub safaridriver: Option<PathBuf>,
#[structopt(long = "headless")]
#[clap(long = "headless")]
/// When running browser tests, run the browser in headless mode without any
/// UI or windows.
pub headless: bool,
#[structopt(long = "mode", short = "m", default_value = "normal")]
#[clap(long = "mode", short = 'm', default_value = "normal")]
/// Sets steps to be run. [possible values: no-install, normal]
pub mode: InstallMode,
#[structopt(long = "release", short = "r")]
#[clap(long = "release", short = 'r')]
/// Build with the release profile.
pub release: bool,
/// Path to the Rust crate, and extra options to pass to `cargo test`.
///
/// If the path is not provided, this command searches up the path from the current dirctory
/// If the path is not provided, this command searches up the path from the current directory.
///
/// This is a workaround to allow wasm pack to provide the same command line interface as `cargo`.
/// See <https://github.com/rustwasm/wasm-pack/pull/851> for more information.
#[structopt(allow_hyphen_values = true)]
pub path_and_extra_options: Vec<String>,
}
@ -108,11 +101,11 @@ pub struct Test {
extra_options: Vec<String>,
}
type TestStep = fn(&mut Test) -> Result<(), Error>;
type TestStep = fn(&mut Test) -> Result<()>;
impl Test {
/// Construct a test command from the given options.
pub fn try_from_opts(test_opts: TestOptions) -> Result<Self, Error> {
pub fn try_from_opts(test_opts: TestOptions) -> Result<Self> {
let TestOptions {
node,
mode,
@ -181,7 +174,7 @@ impl Test {
}
/// Execute this test command.
pub fn run(mut self) -> Result<(), Error> {
pub fn run(mut self) -> Result<()> {
let process_steps = self.get_process_steps();
let started = Instant::now();
@ -249,21 +242,21 @@ impl Test {
}
}
fn step_check_rustc_version(&mut self) -> Result<(), Error> {
fn step_check_rustc_version(&mut self) -> Result<()> {
info!("Checking rustc version...");
let _ = build::check_rustc_version()?;
info!("Rustc version is correct.");
Ok(())
}
fn step_check_for_wasm_target(&mut self) -> Result<(), Error> {
fn step_check_for_wasm_target(&mut self) -> Result<()> {
info!("Adding wasm-target...");
build::wasm_target::check_for_wasm32_target()?;
info!("Adding wasm-target was successful.");
Ok(())
}
fn step_build_tests(&mut self) -> Result<(), Error> {
fn step_build_tests(&mut self) -> Result<()> {
info!("Compiling tests to wasm...");
// If the user has run `wasm-pack test -- --features "f1" -- test_name`, then we want to only pass through
@ -280,7 +273,7 @@ impl Test {
Ok(())
}
fn step_install_wasm_bindgen(&mut self) -> Result<(), Error> {
fn step_install_wasm_bindgen(&mut self) -> Result<()> {
info!("Identifying wasm-bindgen dependency...");
let lockfile = Lockfile::new(&self.crate_data)?;
let bindgen_version = lockfile.require_wasm_bindgen()?;
@ -315,7 +308,7 @@ impl Test {
Ok(())
}
fn step_test_node(&mut self) -> Result<(), Error> {
fn step_test_node(&mut self) -> Result<()> {
assert!(self.node);
info!("Running tests in node...");
test::cargo_test_wasm(
@ -334,7 +327,7 @@ impl Test {
Ok(())
}
fn step_get_chromedriver(&mut self) -> Result<(), Error> {
fn step_get_chromedriver(&mut self) -> Result<()> {
assert!(self.chrome && self.chromedriver.is_none());
self.chromedriver = Some(webdriver::get_or_install_chromedriver(
@ -344,7 +337,7 @@ impl Test {
Ok(())
}
fn step_test_chrome(&mut self) -> Result<(), Error> {
fn step_test_chrome(&mut self) -> Result<()> {
let chromedriver = self.chromedriver.as_ref().unwrap().display().to_string();
let chromedriver = chromedriver.as_str();
info!(
@ -359,7 +352,7 @@ impl Test {
Ok(())
}
fn step_get_geckodriver(&mut self) -> Result<(), Error> {
fn step_get_geckodriver(&mut self) -> Result<()> {
assert!(self.firefox && self.geckodriver.is_none());
self.geckodriver = Some(webdriver::get_or_install_geckodriver(
@ -369,7 +362,7 @@ impl Test {
Ok(())
}
fn step_test_firefox(&mut self) -> Result<(), Error> {
fn step_test_firefox(&mut self) -> Result<()> {
let geckodriver = self.geckodriver.as_ref().unwrap().display().to_string();
let geckodriver = geckodriver.as_str();
info!(
@ -384,14 +377,14 @@ impl Test {
Ok(())
}
fn step_get_safaridriver(&mut self) -> Result<(), Error> {
fn step_get_safaridriver(&mut self) -> Result<()> {
assert!(self.safari && self.safaridriver.is_none());
self.safaridriver = Some(webdriver::get_safaridriver()?);
Ok(())
}
fn step_test_safari(&mut self) -> Result<(), Error> {
fn step_test_safari(&mut self) -> Result<()> {
let safaridriver = self.safaridriver.as_ref().unwrap().display().to_string();
let safaridriver = safaridriver.as_str();
info!(

@ -1,7 +1,7 @@
//! Utility functions for commands.
#![allow(clippy::redundant_closure)]
use failure;
use anyhow::Result;
use std::fs;
use std::path::{Path, PathBuf};
use std::time::Duration;
@ -9,7 +9,7 @@ use walkdir::WalkDir;
/// If an explicit path is given, then use it, otherwise assume the current
/// directory is the crate path.
pub fn get_crate_path(path: Option<PathBuf>) -> Result<PathBuf, failure::Error> {
pub fn get_crate_path(path: Option<PathBuf>) -> Result<PathBuf> {
match path {
Some(p) => Ok(p),
None => find_manifest_from_cwd(),
@ -19,7 +19,7 @@ pub fn get_crate_path(path: Option<PathBuf>) -> Result<PathBuf, failure::Error>
/// Search up the path for the manifest file from the current working directory
/// If we don't find the manifest file then return back the current working directory
/// to provide the appropriate error
fn find_manifest_from_cwd() -> Result<PathBuf, failure::Error> {
fn find_manifest_from_cwd() -> Result<PathBuf> {
let mut parent_path = std::env::current_dir()?;
let mut manifest_path = parent_path.join("Cargo.toml");
loop {
@ -36,8 +36,8 @@ fn find_manifest_from_cwd() -> Result<PathBuf, failure::Error> {
}
/// Construct our `pkg` directory in the crate.
pub fn create_pkg_dir(out_dir: &Path) -> Result<(), failure::Error> {
let _ = fs::remove_dir_all(&out_dir); // Clean up any existing directory and ignore errors
pub fn create_pkg_dir(out_dir: &Path) -> Result<()> {
let _ = fs::remove_file(out_dir.join("package.json")); // Clean up package.json from previous runs
fs::create_dir_all(&out_dir)?;
fs::write(out_dir.join(".gitignore"), "*")?;
Ok(())

@ -1,18 +1,14 @@
//! Functionality related to running `cargo-generate`.
use child;
use emoji;
use failure::{self, ResultExt};
use install::{self, Tool};
use crate::child;
use crate::emoji;
use crate::install::{self, Tool};
use anyhow::{Context, Result};
use std::process::Command;
/// Run `cargo generate` in the current directory to create a new
/// project from a template
pub fn generate(
template: &str,
name: &str,
install_status: &install::Status,
) -> Result<(), failure::Error> {
pub fn generate(template: &str, name: &str, install_status: &install::Status) -> Result<()> {
let bin_path = install::get_tool_path(install_status, Tool::CargoGenerate)?
.binary(&Tool::CargoGenerate.to_string())?;
let mut cmd = Command::new(&bin_path);

@ -0,0 +1,41 @@
use anyhow::{bail, Result};
use std::fmt;
use crate::target;
/// An enum representing supported architectures
#[derive(Clone, PartialEq, Eq)]
pub enum Arch {
/// x86 64-bit
X86_64,
/// x86 32-bit
X86,
/// ARM 64-bit
AArch64,
}
impl Arch {
/// Gets the current architecture
pub fn get() -> Result<Self> {
if target::x86_64 {
Ok(Arch::X86_64)
} else if target::x86 {
Ok(Arch::X86)
} else if target::aarch64 {
Ok(Arch::AArch64)
} else {
bail!("Unrecognized target!")
}
}
}
impl fmt::Display for Arch {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let s = match self {
Arch::X86_64 => "x86-64",
Arch::X86 => "x86",
Arch::AArch64 => "aarch64",
};
write!(f, "{}", s)
}
}

@ -1,5 +1,7 @@
use install::Tool;
use crate::install::Tool;
use anyhow::Result;
use serde::Deserialize;
const VERSION: Option<&str> = option_env!("CARGO_PKG_VERSION");
#[derive(Debug, Deserialize)]
pub struct Krate {
@ -13,12 +15,16 @@ pub struct KrateResponse {
}
impl Krate {
pub fn new(name: &Tool) -> Result<Krate, failure::Error> {
pub fn new(name: &Tool) -> Result<Krate> {
let krate_address = format!("https://crates.io/api/v1/crates/{}", name);
let client = reqwest::Client::new();
let mut res = client.get(&krate_address).send()?;
let res = ureq::get(&krate_address)
.set(
"user-agent",
&format!("wasm-pack/{}", VERSION.unwrap_or("unknown")),
)
.call()?;
let kr: KrateResponse = serde_json::from_str(&res.text()?)?;
let kr: KrateResponse = res.into_json()?;
Ok(kr.krate)
}
}

@ -1,25 +1,28 @@
//! Functionality related to installing prebuilt binaries and/or running cargo install.
use self::krate::Krate;
use crate::child;
use crate::emoji;
use crate::install;
use crate::PBAR;
use anyhow::{anyhow, bail, Context, Result};
use binary_install::{Cache, Download};
use child;
use emoji;
use failure::{self, ResultExt};
use install;
use log::debug;
use log::{info, warn};
use std::env;
use std::fs;
use std::path::Path;
use std::process::Command;
use target;
use which::which;
use PBAR;
mod arch;
mod krate;
mod mode;
mod os;
mod tool;
pub use self::arch::Arch;
pub use self::mode::InstallMode;
pub use self::os::Os;
pub use self::tool::Tool;
/// Possible outcomes of attempting to find/install a tool
@ -33,7 +36,7 @@ pub enum Status {
}
/// Handles possible installs status and returns the download or a error message
pub fn get_tool_path(status: &Status, tool: Tool) -> Result<&Download, failure::Error> {
pub fn get_tool_path(status: &Status, tool: Tool) -> Result<&Download> {
match status {
Status::Found(download) => Ok(download),
Status::CannotInstall => bail!("Not able to find or install a local {}.", tool),
@ -54,7 +57,7 @@ pub fn download_prebuilt_or_cargo_install(
cache: &Cache,
version: &str,
install_permitted: bool,
) -> Result<Status, failure::Error> {
) -> Result<Status> {
// If the tool is installed globally and it has the right version, use
// that. Assume that other tools are installed next to it.
//
@ -86,11 +89,7 @@ pub fn download_prebuilt_or_cargo_install(
}
/// Check if the tool dependency is locally satisfied.
pub fn check_version(
tool: &Tool,
path: &Path,
expected_version: &str,
) -> Result<bool, failure::Error> {
pub fn check_version(tool: &Tool, path: &Path, expected_version: &str) -> Result<bool> {
let expected_version = if expected_version == "latest" {
let krate = Krate::new(tool)?;
krate.max_version
@ -107,7 +106,7 @@ pub fn check_version(
}
/// Fetches the version of a CLI tool
pub fn get_cli_version(tool: &Tool, path: &Path) -> Result<String, failure::Error> {
pub fn get_cli_version(tool: &Tool, path: &Path) -> Result<String> {
let mut cmd = Command::new(path);
cmd.arg("--version");
let stdout = child::run_capture_stdout(cmd, tool)?;
@ -124,7 +123,7 @@ pub fn download_prebuilt(
cache: &Cache,
version: &str,
install_permitted: bool,
) -> Result<Status, failure::Error> {
) -> Result<Status> {
let url = match prebuilt_url(tool, version) {
Ok(url) => url,
Err(e) => bail!(
@ -149,7 +148,11 @@ pub fn download_prebuilt(
}
}
Tool::WasmOpt => {
let binaries = &["wasm-opt"];
let binaries: &[&str] = match Os::get()? {
Os::MacOS => &["bin/wasm-opt", "lib/libbinaryen.dylib"],
Os::Linux => &["bin/wasm-opt"],
Os::Windows => &["bin/wasm-opt.exe"],
};
match cache.download(install_permitted, "wasm-opt", binaries, &url)? {
Some(download) => Ok(Status::Found(download)),
// TODO(ag_dubs): why is this different? i forget...
@ -161,33 +164,25 @@ pub fn download_prebuilt(
/// Returns the URL of a precompiled version of wasm-bindgen, if we have one
/// available for our host platform.
fn prebuilt_url(tool: &Tool, version: &str) -> Result<String, failure::Error> {
let target = if target::LINUX && target::x86_64 {
match tool {
Tool::WasmOpt => "x86-linux",
_ => "x86_64-unknown-linux-musl",
}
} else if target::LINUX && target::x86 {
match tool {
Tool::WasmOpt => "x86-linux",
_ => bail!("Unrecognized target!"),
}
} else if target::MACOS && target::x86_64 {
"x86_64-apple-darwin"
} else if target::WINDOWS && target::x86_64 {
match tool {
Tool::WasmOpt => "x86-windows",
_ => "x86_64-pc-windows-msvc",
}
} else if target::WINDOWS && target::x86 {
match tool {
Tool::WasmOpt => "x86-windows",
fn prebuilt_url(tool: &Tool, version: &str) -> Result<String> {
let os = Os::get()?;
let arch = Arch::get()?;
prebuilt_url_for(tool, version, &arch, &os)
}
/// Get the download URL for some tool at some version, architecture and operating system
pub fn prebuilt_url_for(tool: &Tool, version: &str, arch: &Arch, os: &Os) -> Result<String> {
let target = match (os, arch, tool) {
(Os::Linux, Arch::X86_64, Tool::WasmOpt) => "x86_64-linux",
(Os::Linux, Arch::X86_64, _) => "x86_64-unknown-linux-musl",
(Os::MacOS, Arch::X86_64, Tool::WasmOpt) => "x86_64-macos",
(Os::MacOS, Arch::X86_64, _) => "x86_64-apple-darwin",
(Os::MacOS, Arch::AArch64, Tool::CargoGenerate) => "aarch64-apple-darwin",
(Os::MacOS, Arch::AArch64, Tool::WasmOpt) => "arm64-macos",
(Os::Windows, Arch::X86_64, Tool::WasmOpt) => "x86_64-windows",
(Os::Windows, Arch::X86_64, _) => "x86_64-pc-windows-msvc",
_ => bail!("Unrecognized target!"),
}
} else {
bail!("Unrecognized target!")
};
match tool {
Tool::WasmBindgen => {
Ok(format!(
@ -199,15 +194,14 @@ fn prebuilt_url(tool: &Tool, version: &str) -> Result<String, failure::Error> {
Tool::CargoGenerate => {
Ok(format!(
"https://github.com/cargo-generate/cargo-generate/releases/download/v{0}/cargo-generate-v{0}-{1}.tar.gz",
// Krate::new(&Tool::CargoGenerate)?.max_version,
"0.5.1", // latest released binary [#907](https://github.com/rustwasm/wasm-pack/issues/907)
"0.18.2",
target
))
},
Tool::WasmOpt => {
Ok(format!(
"https://github.com/WebAssembly/binaryen/releases/download/{vers}/binaryen-{vers}-{target}.tar.gz",
vers = "version_90",
vers = "version_111",
target = target,
))
}
@ -221,7 +215,7 @@ pub fn cargo_install(
cache: &Cache,
version: &str,
install_permitted: bool,
) -> Result<Status, failure::Error> {
) -> Result<Status> {
debug!(
"Attempting to use a `cargo install`ed version of `{}={}`",
tool, version,
@ -276,7 +270,7 @@ pub fn cargo_install(
// just want them in `$root/*` directly (which matches how the tarballs are
// laid out, and where the rest of our code expects them to be). So we do a
// little renaming here.
let binaries: Result<Vec<&str>, failure::Error> = match tool {
let binaries: Result<Vec<&str>> = match tool {
Tool::WasmBindgen => Ok(vec!["wasm-bindgen", "wasm-bindgen-test-runner"]),
Tool::CargoGenerate => Ok(vec!["cargo-generate"]),
Tool::WasmOpt => bail!("Cannot install wasm-opt with cargo."),
@ -288,8 +282,8 @@ pub fn cargo_install(
.join(b)
.with_extension(env::consts::EXE_EXTENSION);
let to = tmp.join(from.file_name().unwrap());
fs::rename(&from, &to).with_context(|_| {
format!(
fs::rename(&from, &to).with_context(|| {
anyhow!(
"failed to move {} to {} for `cargo install`ed `{}`",
from.display(),
to.display(),

@ -1,3 +1,4 @@
use anyhow::{bail, Error, Result};
use std::str::FromStr;
/// The `InstallMode` determines which mode of initialization we are running, and
@ -20,8 +21,8 @@ impl Default for InstallMode {
}
impl FromStr for InstallMode {
type Err = failure::Error;
fn from_str(s: &str) -> Result<Self, failure::Error> {
type Err = Error;
fn from_str(s: &str) -> Result<Self> {
match s {
"no-install" => Ok(InstallMode::Noinstall),
"normal" => Ok(InstallMode::Normal),

@ -0,0 +1,41 @@
use anyhow::{bail, Result};
use std::fmt;
use crate::target;
/// An enum representing supported operating systems
#[derive(Clone, PartialEq, Eq)]
pub enum Os {
/// Linux operating system
Linux,
/// Macos operating system
MacOS,
/// Windows operating system
Windows,
}
impl Os {
/// Get the current operating system
pub fn get() -> Result<Self> {
if target::LINUX {
Ok(Os::Linux)
} else if target::MACOS {
Ok(Os::MacOS)
} else if target::WINDOWS {
Ok(Os::Windows)
} else {
bail!("Unrecognized target!")
}
}
}
impl fmt::Display for Os {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let s = match self {
Os::Linux => "linux",
Os::MacOS => "macOS",
Os::Windows => "windows",
};
write!(f, "{}", s)
}
}

@ -22,14 +22,14 @@ use std::io;
use std::path::Path;
use std::process;
use anyhow::{anyhow, bail, Context, Result};
use atty;
use failure::{self, ResultExt};
use which;
pub fn install() -> ! {
if let Err(e) = do_install() {
eprintln!("{}", e);
for cause in e.iter_causes() {
for cause in e.chain() {
eprintln!("Caused by: {}", cause);
}
}
@ -47,7 +47,7 @@ pub fn install() -> ! {
process::exit(0);
}
fn do_install() -> Result<(), failure::Error> {
fn do_install() -> Result<()> {
// Find `rustup.exe` in PATH, we'll be using its installation directory as
// our installation directory.
let rustup = match which::which("rustup") {
@ -74,7 +74,7 @@ fn do_install() -> Result<(), failure::Error> {
// Our relatively simple install step!
let me = env::current_exe()?;
fs::copy(&me, &destination)
.with_context(|_| format!("failed to copy executable to `{}`", destination.display()))?;
.with_context(|| anyhow!("failed to copy executable to `{}`", destination.display()))?;
println!(
"info: successfully installed wasm-pack to `{}`",
destination.display()
@ -85,7 +85,7 @@ fn do_install() -> Result<(), failure::Error> {
Ok(())
}
fn confirm_can_overwrite(dst: &Path) -> Result<(), failure::Error> {
fn confirm_can_overwrite(dst: &Path) -> Result<()> {
// If the `-f` argument was passed, we can always overwrite everything.
if env::args().any(|arg| arg == "-f") {
return Ok(());
@ -112,7 +112,7 @@ fn confirm_can_overwrite(dst: &Path) -> Result<(), failure::Error> {
let mut line = String::new();
io::stdin()
.read_line(&mut line)
.with_context(|_| "failed to read stdin")?;
.context("failed to read stdin")?;
if line.starts_with('y') || line.starts_with('Y') {
return Ok(());

@ -2,27 +2,23 @@
#![deny(missing_docs)]
extern crate anyhow;
extern crate cargo_metadata;
extern crate console;
extern crate strsim;
#[macro_use]
extern crate failure;
extern crate glob;
extern crate parking_lot;
extern crate semver;
extern crate serde;
extern crate strsim;
extern crate which;
#[macro_use]
extern crate serde_derive;
extern crate serde_ignored;
extern crate serde_json;
#[macro_use]
extern crate structopt;
extern crate binary_install;
extern crate chrono;
extern crate curl;
extern crate dialoguer;
extern crate log;
extern crate serde_ignored;
extern crate serde_json;
extern crate toml;
extern crate walkdir;
@ -45,27 +41,30 @@ pub mod target;
pub mod test;
pub mod wasm_opt;
use progressbar::{LogLevel, ProgressOutput};
use crate::progressbar::{LogLevel, ProgressOutput};
use clap::builder::ArgAction;
use clap::Parser;
/// The global progress bar and user-facing message output.
pub static PBAR: ProgressOutput = ProgressOutput::new();
/// 📦 ✨ pack and publish your wasm!
#[derive(Debug, StructOpt)]
#[derive(Debug, Parser)]
#[command(version)]
pub struct Cli {
/// The subcommand to run.
#[structopt(subcommand)] // Note that we mark a field as a subcommand
#[clap(subcommand)] // Note that we mark a field as a subcommand
pub cmd: command::Command,
/// Log verbosity is based off the number of v used
#[structopt(long = "verbose", short = "v", parse(from_occurrences))]
#[clap(long = "verbose", short = 'v', action = ArgAction::Count)]
pub verbosity: u8,
#[structopt(long = "quiet", short = "q")]
#[clap(long = "quiet", short = 'q')]
/// No output printed to stdout
pub quiet: bool,
#[structopt(long = "log-level", default_value = "info")]
#[clap(long = "log-level", default_value = "info")]
/// The maximum level of messages that should be logged by wasm-pack. [possible values: info, warn, error]
pub log_level: LogLevel,
}

@ -1,21 +1,19 @@
//! Copy `LICENSE` file(s) for the packaged wasm.
use failure;
use anyhow::{anyhow, Result};
use std::fs;
use std::path::Path;
use crate::manifest::CrateData;
use crate::PBAR;
use glob::glob;
use manifest::CrateData;
use PBAR;
fn glob_license_files(path: &Path) -> Result<Vec<String>, failure::Error> {
fn glob_license_files(path: &Path) -> Result<Vec<String>> {
let mut license_files: Vec<String> = Vec::new();
let path_string = match path.join("LICENSE*").to_str() {
Some(path_string) => path_string.to_owned(),
None => {
return Err(format_err!(
"Could not convert joined license path to String"
));
return Err(anyhow!("Could not convert joined license path to String"));
}
};
@ -24,11 +22,11 @@ fn glob_license_files(path: &Path) -> Result<Vec<String>, failure::Error> {
Ok(globed_path) => {
let file_name = match globed_path.file_name() {
Some(file_name) => file_name,
None => return Err(format_err!("Could not get file name from path")),
None => return Err(anyhow!("Could not get file name from path")),
};
let file_name_string = match file_name.to_str() {
Some(file_name_string) => file_name_string.to_owned(),
None => return Err(format_err!("Could not convert filename to String")),
None => return Err(anyhow!("Could not convert filename to String")),
};
license_files.push(file_name_string);
}
@ -39,11 +37,7 @@ fn glob_license_files(path: &Path) -> Result<Vec<String>, failure::Error> {
}
/// Copy the crate's license into the `pkg` directory.
pub fn copy_from_crate(
crate_data: &CrateData,
path: &Path,
out_dir: &Path,
) -> Result<(), failure::Error> {
pub fn copy_from_crate(crate_data: &CrateData, path: &Path, out_dir: &Path) -> Result<()> {
assert!(
fs::metadata(path).ok().map_or(false, |m| m.is_dir()),
"crate directory should exist"

@ -5,9 +5,9 @@
use std::fs;
use std::path::PathBuf;
use crate::manifest::CrateData;
use anyhow::{anyhow, bail, Context, Result};
use console::style;
use failure::{Error, ResultExt};
use manifest::CrateData;
use toml;
/// This struct represents the contents of `Cargo.lock`.
@ -25,12 +25,12 @@ struct Package {
impl Lockfile {
/// Read the `Cargo.lock` file for the crate at the given path.
pub fn new(crate_data: &CrateData) -> Result<Lockfile, Error> {
pub fn new(crate_data: &CrateData) -> Result<Lockfile> {
let lock_path = get_lockfile_path(crate_data)?;
let lockfile = fs::read_to_string(&lock_path)
.with_context(|_| format!("failed to read: {}", lock_path.display()))?;
.with_context(|| anyhow!("failed to read: {}", lock_path.display()))?;
let lockfile = toml::from_str(&lockfile)
.with_context(|_| format!("failed to parse: {}", lock_path.display()))?;
.with_context(|| anyhow!("failed to parse: {}", lock_path.display()))?;
Ok(lockfile)
}
@ -41,9 +41,9 @@ impl Lockfile {
/// Like `wasm_bindgen_version`, except it returns an error instead of
/// `None`.
pub fn require_wasm_bindgen(&self) -> Result<&str, Error> {
pub fn require_wasm_bindgen(&self) -> Result<&str> {
self.wasm_bindgen_version().ok_or_else(|| {
format_err!(
anyhow!(
"Ensure that you have \"{}\" as a dependency in your Cargo.toml file:\n\
[dependencies]\n\
wasm-bindgen = \"0.2\"",
@ -65,9 +65,9 @@ impl Lockfile {
}
}
/// Given the path to the crate that we are buliding, return a `PathBuf`
/// Given the path to the crate that we are building, return a `PathBuf`
/// containing the location of the lock file, by finding the workspace root.
fn get_lockfile_path(crate_data: &CrateData) -> Result<PathBuf, Error> {
fn get_lockfile_path(crate_data: &CrateData) -> Result<PathBuf> {
// Check that a lock file can be found in the directory. Return an error
// if it cannot, otherwise return the path buffer.
let lockfile_path = crate_data.workspace_root().join("Cargo.lock");

@ -1,20 +1,20 @@
#![allow(clippy::redundant_closure, clippy::redundant_pattern_matching)]
extern crate anyhow;
extern crate atty;
extern crate clap;
extern crate env_logger;
#[macro_use]
extern crate failure;
extern crate human_panic;
extern crate log;
extern crate structopt;
extern crate wasm_pack;
extern crate which;
use anyhow::Result;
use clap::Parser;
use std::env;
use std::panic;
use std::sync::mpsc;
use std::thread;
use structopt::StructOpt;
use wasm_pack::{
build::{self, WasmPackVersion},
command::run_wasm_pack,
@ -23,7 +23,7 @@ use wasm_pack::{
mod installer;
fn background_check_for_updates() -> mpsc::Receiver<Result<WasmPackVersion, failure::Error>> {
fn background_check_for_updates() -> mpsc::Receiver<Result<WasmPackVersion>> {
let (sender, receiver) = mpsc::channel();
let _detached_thread = thread::spawn(move || {
@ -51,14 +51,14 @@ fn main() {
if let Err(e) = run() {
eprintln!("Error: {}", e);
for cause in e.iter_causes() {
for cause in e.chain() {
eprintln!("Caused by: {}", cause);
}
::std::process::exit(1);
}
}
fn run() -> Result<(), failure::Error> {
fn run() -> Result<()> {
let wasm_pack_version = background_check_for_updates();
// Deprecate `init`
@ -79,7 +79,7 @@ fn run() -> Result<(), failure::Error> {
}
}
let args = Cli::from_args();
let args = Cli::parse();
PBAR.set_log_level(args.log_level);

@ -6,6 +6,7 @@
clippy::redundant_closure
)]
use anyhow::{anyhow, bail, Context, Result};
mod npm;
use std::path::Path;
@ -14,12 +15,11 @@ use std::{collections::HashMap, fs};
use self::npm::{
repository::Repository, CommonJSPackage, ESModulesPackage, NoModulesPackage, NpmPackage,
};
use crate::command::build::{BuildProfile, Target};
use crate::PBAR;
use cargo_metadata::Metadata;
use chrono::offset;
use chrono::DateTime;
use command::build::{BuildProfile, Target};
use curl::easy;
use failure::{Error, ResultExt};
use serde::{self, Deserialize};
use serde_json;
use std::collections::BTreeSet;
@ -27,7 +27,6 @@ use std::env;
use std::io::Write;
use strsim::levenshtein;
use toml;
use PBAR;
const WASM_PACK_METADATA_KEY: &str = "package.metadata.wasm-pack";
const WASM_PACK_VERSION: Option<&'static str> = option_env!("CARGO_PKG_VERSION");
@ -50,12 +49,6 @@ pub struct CargoManifest {
#[derive(Deserialize)]
struct CargoPackage {
name: String,
description: Option<String>,
license: Option<String>,
#[serde(rename = "license-file")]
license_file: Option<String>,
repository: Option<String>,
homepage: Option<String>,
#[serde(default)]
metadata: CargoMetadata,
@ -124,15 +117,9 @@ struct CargoWasmPackProfileWasmBindgen {
#[serde(default, rename = "dwarf-debug-info")]
dwarf_debug_info: Option<bool>,
}
struct Collector(Vec<u8>);
impl easy::Handler for Collector {
fn write(&mut self, data: &[u8]) -> Result<usize, easy::WriteError> {
self.0.extend_from_slice(data);
Ok(data.len())
}
#[serde(default, rename = "omit-default-module-path")]
omit_default_module_path: Option<bool>,
}
/// Struct for storing information received from crates.io
@ -149,7 +136,7 @@ struct CrateInformation {
impl Crate {
/// Returns latest wasm-pack version
pub fn return_wasm_pack_latest_version() -> Result<Option<String>, failure::Error> {
pub fn return_wasm_pack_latest_version() -> Result<Option<String>> {
let current_time = chrono::offset::Local::now();
let old_metadata_file = Self::return_wasm_pack_file();
@ -172,9 +159,7 @@ impl Crate {
}
}
fn return_api_call_result(
current_time: DateTime<offset::Local>,
) -> Result<String, failure::Error> {
fn return_api_call_result(current_time: DateTime<offset::Local>) -> Result<String> {
let version = Self::return_latest_wasm_pack_version();
// We always override the stamp file with the current time because we don't
@ -192,7 +177,7 @@ impl Crate {
fn override_stamp_file(
current_time: DateTime<offset::Local>,
version: Option<&str>,
) -> Result<(), failure::Error> {
) -> Result<()> {
let path = env::current_exe()?;
let mut file = fs::OpenOptions::new()
@ -224,7 +209,7 @@ impl Crate {
}
/// Returns wasm-pack latest version (if it's received) by executing check_wasm_pack_latest_version function.
fn return_latest_wasm_pack_version() -> Result<String, failure::Error> {
fn return_latest_wasm_pack_version() -> Result<String> {
Self::check_wasm_pack_latest_version().map(|crt| crt.crt.max_version)
}
@ -239,28 +224,26 @@ impl Crate {
}
/// Call to the crates.io api and return the latest version of `wasm-pack`
fn check_wasm_pack_latest_version() -> Result<Crate, Error> {
fn check_wasm_pack_latest_version() -> Result<Crate> {
let url = "https://crates.io/api/v1/crates/wasm-pack";
let mut easy = easy::Easy2::new(Collector(Vec::new()));
easy.useragent(&format!(
let agent = ureq::builder()
.user_agent(&format!(
"wasm-pack/{} ({})",
WASM_PACK_VERSION.unwrap_or_else(|| "unknown"),
WASM_PACK_REPO_URL
))?;
))
.build();
let resp = agent
.get(url)
.call()
.context("failed to get wasm-pack version")?;
easy.url(url)?;
easy.get(true)?;
easy.perform()?;
let status_code = easy.response_code()?;
let status_code = resp.status();
if 200 <= status_code && status_code < 300 {
let contents = easy.get_ref();
let result = String::from_utf8_lossy(&contents.0);
let json = resp.into_json()?;
Ok(serde_json::from_str(result.into_owned().as_str())?)
Ok(json)
} else {
bail!(
"Received a bad HTTP status code ({}) when checking for newer wasm-pack version at: {}",
@ -291,6 +274,7 @@ impl CargoWasmPackProfile {
debug_js_glue: Some(true),
demangle_name_section: Some(true),
dwarf_debug_info: Some(false),
omit_default_module_path: Some(false),
},
wasm_opt: None,
}
@ -302,6 +286,7 @@ impl CargoWasmPackProfile {
debug_js_glue: Some(false),
demangle_name_section: Some(true),
dwarf_debug_info: Some(false),
omit_default_module_path: Some(false),
},
wasm_opt: Some(CargoWasmPackProfileWasmOpt::Enabled(true)),
}
@ -313,6 +298,7 @@ impl CargoWasmPackProfile {
debug_js_glue: Some(false),
demangle_name_section: Some(true),
dwarf_debug_info: Some(false),
omit_default_module_path: Some(false),
},
wasm_opt: Some(CargoWasmPackProfileWasmOpt::Enabled(true)),
}
@ -354,6 +340,7 @@ impl CargoWasmPackProfile {
d!(wasm_bindgen.debug_js_glue);
d!(wasm_bindgen.demangle_name_section);
d!(wasm_bindgen.dwarf_debug_info);
d!(wasm_bindgen.omit_default_module_path);
if self.wasm_opt.is_none() {
self.wasm_opt = defaults.wasm_opt.clone();
@ -375,6 +362,11 @@ impl CargoWasmPackProfile {
self.wasm_bindgen.dwarf_debug_info.unwrap()
}
/// Get this profile's configured `[wasm-bindgen.omit-default-module-path]` value.
pub fn wasm_bindgen_omit_default_module_path(&self) -> bool {
self.wasm_bindgen.omit_default_module_path.unwrap()
}
/// Get this profile's configured arguments for `wasm-opt`, if enabled.
pub fn wasm_opt_args(&self) -> Option<Vec<String>> {
match self.wasm_opt.as_ref()? {
@ -403,7 +395,7 @@ pub struct ManifestAndUnsedKeys {
impl CrateData {
/// Reads all metadata for the crate whose manifest is inside the directory
/// specified by `path`.
pub fn new(crate_path: &Path, out_name: Option<String>) -> Result<CrateData, Error> {
pub fn new(crate_path: &Path, out_name: Option<String>) -> Result<CrateData> {
let manifest_path = crate_path.join("Cargo.toml");
if !manifest_path.is_file() {
bail!(
@ -426,9 +418,9 @@ impl CrateData {
.iter()
.position(|pkg| {
pkg.name == manifest.package.name
&& CrateData::is_same_path(&pkg.manifest_path, &manifest_path)
&& CrateData::is_same_path(pkg.manifest_path.as_std_path(), &manifest_path)
})
.ok_or_else(|| format_err!("failed to find package in metadata"))?;
.ok_or_else(|| anyhow!("failed to find package in metadata"))?;
Ok(CrateData {
data,
@ -454,10 +446,10 @@ impl CrateData {
/// # 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> {
pub fn parse_crate_data(manifest_path: &Path) -> Result<ManifestAndUnsedKeys> {
let manifest = fs::read_to_string(&manifest_path)
.with_context(|_| format!("failed to read: {}", manifest_path.display()))?;
let manifest = &mut toml::Deserializer::new(&manifest);
.with_context(|| anyhow!("failed to read: {}", manifest_path.display()))?;
let manifest = toml::Deserializer::new(&manifest);
let mut unused_keys = BTreeSet::new();
let levenshtein_threshold = 1;
@ -472,7 +464,7 @@ impl CrateData {
unused_keys.insert(path_string);
}
})
.with_context(|_| format!("failed to parse manifest: {}", manifest_path.display()))?;
.with_context(|| anyhow!("failed to parse manifest: {}", manifest_path.display()))?;
Ok(ManifestAndUnsedKeys {
manifest,
@ -501,12 +493,12 @@ impl CrateData {
}
/// Check that the crate the given path is properly configured.
pub fn check_crate_config(&self) -> Result<(), Error> {
pub fn check_crate_config(&self) -> Result<()> {
self.check_crate_type()?;
Ok(())
}
fn check_crate_type(&self) -> Result<(), Error> {
fn check_crate_type(&self) -> Result<()> {
let pkg = &self.data.packages[self.current_idx];
let any_cdylib = pkg
.targets
@ -524,9 +516,13 @@ impl CrateData {
)
}
fn pkg(&self) -> &cargo_metadata::Package {
&self.data.packages[self.current_idx]
}
/// Get the crate name for the crate at the given path.
pub fn crate_name(&self) -> String {
let pkg = &self.data.packages[self.current_idx];
let pkg = self.pkg();
match pkg
.targets
.iter()
@ -545,14 +541,25 @@ impl CrateData {
}
}
/// Gets the optional path to the readme, or None if disabled.
pub fn crate_readme(&self) -> Option<String> {
self.pkg()
.readme
.clone()
.map(|readme_file| readme_file.into_string())
}
/// Get the license for the crate at the given path.
pub fn crate_license(&self) -> &Option<String> {
&self.manifest.package.license
&self.pkg().license
}
/// Get the license file path for the crate at the given path.
pub fn crate_license_file(&self) -> &Option<String> {
&self.manifest.package.license_file
pub fn crate_license_file(&self) -> Option<String> {
self.pkg()
.license_file
.clone()
.map(|license_file| license_file.into_string())
}
/// Returns the path to this project's target directory where artifacts are
@ -573,7 +580,7 @@ impl CrateData {
scope: &Option<String>,
disable_dts: bool,
target: Target,
) -> Result<(), Error> {
) -> Result<()> {
let pkg_file_path = out_dir.join("package.json");
// Check if a `package.json` was already generated by wasm-bindgen, if so
// we merge the NPM dependencies already specified in it.
@ -590,12 +597,14 @@ impl CrateData {
Target::NoModules => self.to_nomodules(scope, disable_dts, existing_deps, out_dir),
Target::Bundler => self.to_esmodules(scope, disable_dts, existing_deps, out_dir),
Target::Web => self.to_web(scope, disable_dts, existing_deps, out_dir),
// Deno does not need package.json
Target::Deno => return Ok(()),
};
let npm_json = serde_json::to_string_pretty(&npm_data)?;
fs::write(&pkg_file_path, npm_json)
.with_context(|_| format!("failed to write: {}", pkg_file_path.display()))?;
.with_context(|| anyhow!("failed to write: {}", pkg_file_path.display()))?;
Ok(())
}
@ -654,14 +663,14 @@ impl CrateData {
dts_file,
files,
main: js_file,
homepage: self.manifest.package.homepage.clone(),
homepage: self.pkg().homepage.clone(),
keywords,
}
}
fn license(&self) -> Option<String> {
self.manifest.package.license.clone().or_else(|| {
self.manifest.package.license_file.clone().map(|file| {
self.crate_license().clone().or_else(|| {
self.crate_license_file().clone().map(|file| {
// When license is written in file: https://docs.npmjs.com/files/package.json#license
format!("SEE LICENSE IN {}", file)
})
@ -683,15 +692,10 @@ impl CrateData {
NpmPackage::CommonJSPackage(CommonJSPackage {
name: data.name,
collaborators: pkg.authors.clone(),
description: self.manifest.package.description.clone(),
description: self.pkg().description.clone(),
version: pkg.version.to_string(),
license: self.license(),
repository: self
.manifest
.package
.repository
.clone()
.map(|repo_url| Repository {
repository: self.pkg().repository.clone().map(|repo_url| Repository {
ty: "git".to_string(),
url: repo_url,
}),
@ -720,23 +724,18 @@ impl CrateData {
name: data.name,
ty: "module".into(),
collaborators: pkg.authors.clone(),
description: self.manifest.package.description.clone(),
description: self.pkg().description.clone(),
version: pkg.version.to_string(),
license: self.license(),
repository: self
.manifest
.package
.repository
.clone()
.map(|repo_url| Repository {
repository: self.pkg().repository.clone().map(|repo_url| Repository {
ty: "git".to_string(),
url: repo_url,
}),
files: data.files,
main: data.main,
main: data.main.clone(),
homepage: data.homepage,
types: data.dts_file,
side_effects: false,
side_effects: vec![format!("./{}", data.main), "./snippets/*".to_owned()],
keywords: data.keywords,
dependencies,
})
@ -758,15 +757,10 @@ impl CrateData {
name: data.name,
ty: "module".into(),
collaborators: pkg.authors.clone(),
description: self.manifest.package.description.clone(),
description: self.pkg().description.clone(),
version: pkg.version.to_string(),
license: self.license(),
repository: self
.manifest
.package
.repository
.clone()
.map(|repo_url| Repository {
repository: self.pkg().repository.clone().map(|repo_url| Repository {
ty: "git".to_string(),
url: repo_url,
}),
@ -774,7 +768,7 @@ impl CrateData {
main: data.main,
homepage: data.homepage,
types: data.dts_file,
side_effects: false,
side_effects: vec!["./snippets/*".to_owned()],
keywords: data.keywords,
dependencies,
})
@ -795,15 +789,10 @@ impl CrateData {
NpmPackage::NoModulesPackage(NoModulesPackage {
name: data.name,
collaborators: pkg.authors.clone(),
description: self.manifest.package.description.clone(),
description: self.pkg().description.clone(),
version: pkg.version.to_string(),
license: self.license(),
repository: self
.manifest
.package
.repository
.clone()
.map(|repo_url| Repository {
repository: self.pkg().repository.clone().map(|repo_url| Repository {
ty: "git".to_string(),
url: repo_url,
}),
@ -818,13 +807,13 @@ impl CrateData {
fn check_optional_fields(&self) {
let mut messages = vec![];
if self.manifest.package.description.is_none() {
if self.pkg().description.is_none() {
messages.push("description");
}
if self.manifest.package.repository.is_none() {
if self.pkg().repository.is_none() {
messages.push("repository");
}
if self.manifest.package.license.is_none() && self.manifest.package.license_file.is_none() {
if self.pkg().license.is_none() && self.pkg().license_file.is_none() {
messages.push("license");
}

@ -1,6 +1,6 @@
use std::collections::HashMap;
use manifest::npm::repository::Repository;
use crate::manifest::npm::repository::Repository;
#[derive(Serialize)]
pub struct CommonJSPackage {

@ -1,6 +1,6 @@
use std::collections::HashMap;
use manifest::npm::repository::Repository;
use crate::manifest::npm::repository::Repository;
#[derive(Serialize)]
pub struct ESModulesPackage {
@ -24,7 +24,7 @@ pub struct ESModulesPackage {
#[serde(skip_serializing_if = "Option::is_none")]
pub types: Option<String>,
#[serde(rename = "sideEffects")]
pub side_effects: bool,
pub side_effects: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub keywords: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]

@ -1,6 +1,6 @@
use std::collections::HashMap;
use manifest::npm::repository::Repository;
use crate::manifest::npm::repository::Repository;
#[derive(Serialize)]
pub struct NoModulesPackage {

@ -1,15 +1,15 @@
//! Functionality related to publishing to npm.
use child;
use command::publish::access::Access;
use failure::{self, ResultExt};
use crate::child;
use crate::command::publish::access::Access;
use anyhow::{bail, Context, Result};
use log::info;
/// The default npm registry used when we aren't working with a custom registry.
pub const DEFAULT_NPM_REGISTRY: &str = "https://registry.npmjs.org/";
/// Run the `npm pack` command.
pub fn npm_pack(path: &str) -> Result<(), failure::Error> {
pub fn npm_pack(path: &str) -> Result<()> {
let mut cmd = child::new_command("npm");
cmd.current_dir(path).arg("pack");
child::run(cmd, "npm pack").context("Packaging up your code failed")?;
@ -17,11 +17,7 @@ pub fn npm_pack(path: &str) -> Result<(), failure::Error> {
}
/// Run the `npm publish` command.
pub fn npm_publish(
path: &str,
access: Option<Access>,
tag: Option<String>,
) -> Result<(), failure::Error> {
pub fn npm_publish(path: &str, access: Option<Access>, tag: Option<String>) -> Result<()> {
let mut cmd = child::new_command("npm");
match access {
Some(a) => cmd.current_dir(path).arg("publish").arg(&a.to_string()),
@ -36,22 +32,13 @@ pub fn npm_publish(
}
/// Run the `npm login` command.
pub fn npm_login(
registry: &str,
scope: &Option<String>,
always_auth: bool,
auth_type: &Option<String>,
) -> Result<(), failure::Error> {
pub fn npm_login(registry: &str, scope: &Option<String>, auth_type: &Option<String>) -> Result<()> {
let mut args = vec!["login".to_string(), format!("--registry={}", registry)];
if let Some(scope) = scope {
args.push(format!("--scope={}", scope));
}
if always_auth {
args.push("--always_auth".to_string());
}
if let Some(auth_type) = auth_type {
args.push(format!("--auth_type={}", auth_type));
}

@ -1,7 +1,8 @@
//! Fancy progress bar functionality.
use crate::emoji;
use anyhow::{bail, Error, Result};
use console::style;
use emoji;
use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
#[repr(u8)]
@ -19,8 +20,8 @@ pub enum LogLevel {
}
impl std::str::FromStr for LogLevel {
type Err = failure::Error;
fn from_str(s: &str) -> Result<Self, failure::Error> {
type Err = Error;
fn from_str(s: &str) -> Result<Self> {
match s {
"error" => Ok(LogLevel::Error),
"warn" => Ok(LogLevel::Warn),

@ -1,13 +1,14 @@
//! Generating `README` files for the packaged wasm.
use failure::{self, ResultExt};
use anyhow::{Context, Result};
use std::fs;
use std::path::Path;
use PBAR;
use crate::manifest::CrateData;
use crate::PBAR;
/// Copy the crate's README into the `pkg` directory.
pub fn copy_from_crate(path: &Path, out_dir: &Path) -> Result<(), failure::Error> {
pub fn copy_from_crate(crate_data: &CrateData, path: &Path, out_dir: &Path) -> Result<()> {
assert!(
fs::metadata(path).ok().map_or(false, |m| m.is_dir()),
"crate directory should exist"
@ -17,7 +18,11 @@ pub fn copy_from_crate(path: &Path, out_dir: &Path) -> Result<(), failure::Error
"crate's pkg directory should exist"
);
let crate_readme_path = path.join("README.md");
let crate_readme_path = match crate_data.crate_readme() {
None => return Ok(()),
Some(readme_path) => path.join(readme_path),
};
let new_readme_path = out_dir.join("README.md");
if crate_readme_path.exists() {
fs::copy(&crate_readme_path, &new_readme_path).context("failed to copy README")?;

@ -1,33 +1,25 @@
//! Key-value store in `*.stamps` file.
use failure::{self, ResultExt};
use anyhow::{anyhow, Context, Result};
use std::{env, fs, path::PathBuf};
/// Get a value corresponding to the key from the JSON value.
///
/// You should use return value of function `read_stamps_file_to_json()` as `json` argument.
pub fn get_stamp_value(
key: impl AsRef<str>,
json: &serde_json::Value,
) -> Result<String, failure::Error> {
pub fn get_stamp_value(key: impl AsRef<str>, json: &serde_json::Value) -> Result<String> {
json.get(key.as_ref())
.and_then(|value| value.as_str().map(ToOwned::to_owned))
.ok_or_else(|| {
failure::err_msg(format!("cannot get stamp value for key '{}'", key.as_ref()))
})
.ok_or_else(|| anyhow!("cannot get stamp value for key '{}'", key.as_ref()))
}
/// Save the key-value pair to the store.
pub fn save_stamp_value(
key: impl Into<String>,
value: impl AsRef<str>,
) -> Result<(), failure::Error> {
pub fn save_stamp_value(key: impl Into<String>, value: impl AsRef<str>) -> Result<()> {
let mut json = read_stamps_file_to_json().unwrap_or_else(|_| serde_json::Map::new().into());
{
let stamps = json
.as_object_mut()
.ok_or_else(|| failure::err_msg("stamps file doesn't contain JSON object"))?;
.ok_or_else(|| anyhow!("stamps file doesn't contain JSON object"))?;
stamps.insert(key.into(), value.as_ref().into());
}
@ -35,7 +27,7 @@ pub fn save_stamp_value(
}
/// Get the path of the `*.stamps` file that is used as the store.
pub fn get_stamps_file_path() -> Result<PathBuf, failure::Error> {
pub fn get_stamps_file_path() -> Result<PathBuf> {
let path = env::current_exe()
.map(|path| path.with_extension("stamps"))
.context("cannot get stamps file path")?;
@ -43,7 +35,7 @@ pub fn get_stamps_file_path() -> Result<PathBuf, failure::Error> {
}
/// Read `*.stamps` file and convert its content to the JSON value.
pub fn read_stamps_file_to_json() -> Result<serde_json::Value, failure::Error> {
pub fn read_stamps_file_to_json() -> Result<serde_json::Value> {
let stamps_file_path = get_stamps_file_path()?;
let stamps_file_content =
fs::read_to_string(stamps_file_path).context("cannot find or read stamps file")?;
@ -52,7 +44,7 @@ pub fn read_stamps_file_to_json() -> Result<serde_json::Value, failure::Error> {
Ok(json)
}
fn write_to_stamps_file(json: serde_json::Value) -> Result<(), failure::Error> {
fn write_to_stamps_file(json: serde_json::Value) -> Result<()> {
let stamps_file_path = get_stamps_file_path()?;
let pretty_json = serde_json::to_string_pretty(&json).context("JSON serialization failed")?;
fs::write(stamps_file_path, pretty_json).context("cannot write to stamps file")?;

@ -13,3 +13,5 @@ pub const WINDOWS: bool = cfg!(target_os = "windows");
pub const x86_64: bool = cfg!(target_arch = "x86_64");
#[allow(non_upper_case_globals)]
pub const x86: bool = cfg!(target_arch = "x86");
#[allow(non_upper_case_globals)]
pub const aarch64: bool = cfg!(target_arch = "aarch64");

@ -2,9 +2,9 @@
pub mod webdriver;
use crate::child;
use crate::PBAR;
use child;
use failure::{self, ResultExt};
use anyhow::{Context, Result};
use std::ffi::OsStr;
use std::path::Path;
use std::process::Command;
@ -16,7 +16,7 @@ pub fn cargo_test_wasm<I, K, V>(
release: bool,
envs: I,
extra_options: &[String],
) -> Result<(), failure::Error>
) -> Result<()>
where
I: IntoIterator<Item = (K, V)>,
K: AsRef<OsStr>,

@ -4,10 +4,10 @@ mod chromedriver;
mod geckodriver;
mod safaridriver;
use crate::PBAR;
use anyhow::Result;
use binary_install::Cache;
use failure;
use std::path::PathBuf;
use PBAR;
pub use self::{
chromedriver::{get_or_install_chromedriver, install_chromedriver},
@ -22,7 +22,7 @@ fn get_and_notify(
installation_allowed: bool,
name: &str,
url: &str,
) -> Result<Option<PathBuf>, failure::Error> {
) -> Result<Option<PathBuf>> {
if let Some(dl) = cache.download(false, name, &[name], url)? {
return Ok(Some(dl.binary(name)?));
}
@ -34,18 +34,3 @@ fn get_and_notify(
None => Ok(None),
}
}
struct Collector(Vec<u8>);
impl Collector {
pub fn take_content(&mut self) -> Vec<u8> {
std::mem::take(&mut self.0)
}
}
impl curl::easy::Handler for Collector {
fn write(&mut self, data: &[u8]) -> Result<usize, curl::easy::WriteError> {
self.0.extend_from_slice(data);
Ok(data.len())
}
}

@ -1,25 +1,22 @@
use super::{get_and_notify, Collector};
use super::get_and_notify;
use crate::install::InstallMode;
use crate::stamps;
use crate::target;
use anyhow::{bail, Context, Result};
use binary_install::Cache;
use chrono::DateTime;
use failure::{self, ResultExt};
use install::InstallMode;
use stamps;
use std::path::PathBuf;
use target;
// Keep it up to date with each `wasm-pack` release.
// https://chromedriver.storage.googleapis.com/LATEST_RELEASE
const DEFAULT_CHROMEDRIVER_VERSION: &str = "91.0.4472.101";
const DEFAULT_CHROMEDRIVER_VERSION: &str = "114.0.5735.90";
const CHROMEDRIVER_LAST_UPDATED_STAMP: &str = "chromedriver_last_updated";
const CHROMEDRIVER_VERSION_STAMP: &str = "chromedriver_version";
/// Get the path to an existing `chromedriver`, or install it if no existing
/// binary is found or if there is a new binary version.
pub fn get_or_install_chromedriver(
cache: &Cache,
mode: InstallMode,
) -> Result<PathBuf, failure::Error> {
pub fn get_or_install_chromedriver(cache: &Cache, mode: InstallMode) -> Result<PathBuf> {
if let Ok(path) = which::which("chromedriver") {
return Ok(path);
}
@ -27,10 +24,7 @@ pub fn get_or_install_chromedriver(
}
/// Download and install a pre-built `chromedriver` binary.
pub fn install_chromedriver(
cache: &Cache,
installation_allowed: bool,
) -> Result<PathBuf, failure::Error> {
pub fn install_chromedriver(cache: &Cache, installation_allowed: bool) -> Result<PathBuf> {
let target = if target::LINUX && target::x86_64 {
"linux64"
} else if target::MACOS && target::x86_64 {
@ -99,7 +93,7 @@ fn get_chromedriver_url(target: &str) -> String {
// ------ `get_chromedriver_url` helpers ------
fn save_chromedriver_version(version: String) -> Result<String, failure::Error> {
fn save_chromedriver_version(version: String) -> Result<String> {
stamps::save_stamp_value(CHROMEDRIVER_VERSION_STAMP, &version)?;
let current_time = chrono::offset::Local::now().to_rfc3339();
@ -122,18 +116,13 @@ fn should_load_chromedriver_version_from_stamp(json: &serde_json::Value) -> bool
}
}
fn fetch_chromedriver_version() -> Result<String, failure::Error> {
let mut handle = curl::easy::Easy2::new(Collector(Vec::new()));
handle
.url("https://chromedriver.storage.googleapis.com/LATEST_RELEASE")
.context("URL to fetch chromedriver's LATEST_RELEASE is invalid")?;
handle
.perform()
.context("fetching of chromedriver's LATEST_RELEASE failed")?;
let content = handle.get_mut().take_content();
let version =
String::from_utf8(content).context("chromedriver's LATEST_RELEASE is not valid UTF-8")?;
fn fetch_chromedriver_version() -> Result<String> {
let version = ureq::get("https://chromedriver.storage.googleapis.com/LATEST_RELEASE")
.call()
.context("fetching of chromedriver's LATEST_RELEASE failed")?
.into_string()
.context("converting chromedriver version response to string failed")?;
Ok(version)
}

@ -1,15 +1,15 @@
use super::{get_and_notify, Collector};
use super::get_and_notify;
use crate::install::InstallMode;
use crate::stamps;
use crate::target;
use anyhow::{anyhow, bail, Context, Result};
use binary_install::Cache;
use chrono::DateTime;
use failure::{self, ResultExt};
use install::InstallMode;
use stamps;
use std::path::PathBuf;
use target;
// Keep it up to date with each `wasm-pack` release.
// https://github.com/mozilla/geckodriver/releases/latest
const DEFAULT_GECKODRIVER_VERSION: &str = "v0.29.1";
const DEFAULT_GECKODRIVER_VERSION: &str = "v0.33.0";
const DEFAULT_WINDOWS_GECKODRIVER_VERSION: &str = "v0.24.0";
const GECKODRIVER_LAST_UPDATED_STAMP: &str = "geckodriver_last_updated";
@ -17,10 +17,7 @@ const GECKODRIVER_VERSION_STAMP: &str = "geckodriver_version";
/// Get the path to an existing `geckodriver`, or install it if no existing
/// binary is found or if there is a new binary version.
pub fn get_or_install_geckodriver(
cache: &Cache,
mode: InstallMode,
) -> Result<PathBuf, failure::Error> {
pub fn get_or_install_geckodriver(cache: &Cache, mode: InstallMode) -> Result<PathBuf> {
// geckodriver Windows binaries >v0.24.0 have an additional
// runtime dependency that we cannot be sure is present on the
// user's machine
@ -38,10 +35,7 @@ pub fn get_or_install_geckodriver(
}
/// Download and install a pre-built `geckodriver` binary.
pub fn install_geckodriver(
cache: &Cache,
installation_allowed: bool,
) -> Result<PathBuf, failure::Error> {
pub fn install_geckodriver(cache: &Cache, installation_allowed: bool) -> Result<PathBuf> {
let (target, ext) = if target::LINUX && target::x86 {
("linux32", "tar.gz")
} else if target::LINUX && target::x86_64 {
@ -83,11 +77,8 @@ pub fn install_geckodriver(
/// - it should be relatively safe because each `geckodriver` supports many `Firefox` versions:
/// https://firefox-source-docs.mozilla.org/testing/geckodriver/Support.html#supported-platforms
fn get_geckodriver_url(target: &str, ext: &str) -> String {
let fetch_and_save_version = || {
fetch_latest_geckodriver_tag_json()
.and_then(get_version_from_json)
.and_then(save_geckodriver_version)
};
let fetch_and_save_version =
|| fetch_latest_geckodriver_tag_json().and_then(save_geckodriver_version);
let geckodriver_version = if target::WINDOWS {
log::info!(
@ -124,7 +115,7 @@ fn get_geckodriver_url(target: &str, ext: &str) -> String {
// ------ `get_geckodriver_url` helpers ------
fn save_geckodriver_version(version: String) -> Result<String, failure::Error> {
fn save_geckodriver_version(version: String) -> Result<String> {
stamps::save_stamp_value(GECKODRIVER_VERSION_STAMP, &version)?;
let current_time = chrono::offset::Local::now().to_rfc3339();
@ -147,43 +138,22 @@ fn should_load_geckodriver_version_from_stamp(json: &serde_json::Value) -> bool
}
}
fn fetch_latest_geckodriver_tag_json() -> Result<String, failure::Error> {
let mut headers = curl::easy::List::new();
headers
.append("Accept: application/json")
.context("cannot fetch geckodriver's latest release data - appending header failed")?;
let mut handle = curl::easy::Easy2::new(Collector(Vec::new()));
handle
.url("https://github.com/mozilla/geckodriver/releases/latest")
.context("URL to fetch geckodriver's latest release data is invalid")?;
handle
.http_headers(headers)
.context("cannot fetch geckodriver's latest release data - setting headers failed")?;
// We will be redirected from the `latest` placeholder to the specific tag name.
handle
.follow_location(true)
.context("cannot fetch geckodriver's latest release data - enabling redirects failed")?;
handle
.perform()
.context("fetching of geckodriver's latest release data failed")?;
let content = handle.get_mut().take_content();
let version = String::from_utf8(content)
.context("geckodriver's latest release data is not valid UTF-8")?;
fn fetch_latest_geckodriver_tag_json() -> Result<String> {
let content: serde_json::Value =
ureq::get("https://github.com/mozilla/geckodriver/releases/latest")
.set("Accept", "application/json")
.call()
.context("fetching of geckodriver's latest release data failed")?
.into_json()?;
Ok(version)
get_version_from_json(content)
}
/// JSON example: `{"id":15227534,"tag_name":"v0.24.0","update_url":"/mozzila...`
fn get_version_from_json(json: impl AsRef<str>) -> Result<String, failure::Error> {
let json: serde_json::Value = serde_json::from_str(json.as_ref())
.context("geckodriver's latest release data is not valid JSON")?;
fn get_version_from_json(json: serde_json::Value) -> Result<String> {
json.get("tag_name")
.and_then(|tag_name| tag_name.as_str().map(ToOwned::to_owned))
.ok_or_else(|| {
failure::err_msg("cannot get `tag_name` from geckodriver's latest release data")
})
.ok_or_else(|| anyhow!("cannot get `tag_name` from geckodriver's latest release data"))
}
fn assemble_geckodriver_url(tag: &str, target: &str, ext: &str) -> String {

@ -1,3 +1,4 @@
use anyhow::{bail, Result};
use std::path::PathBuf;
/// Get the path to an existing `safaridriver`.
@ -5,7 +6,7 @@ use std::path::PathBuf;
/// We can't install `safaridriver` if an existing one is not found because
/// Apple does not provide pre-built binaries. However, `safaridriver` *should*
/// be present by default.
pub fn get_safaridriver() -> Result<PathBuf, failure::Error> {
pub fn get_safaridriver() -> Result<PathBuf> {
match which::which("safaridriver") {
Ok(p) => Ok(p),
Err(_) => bail!("could not find `safaridriver` on the `$PATH`"),

@ -1,33 +1,23 @@
//! Support for downloading and executing `wasm-opt`
use crate::child;
use crate::install::{self, Tool};
use crate::install;
use crate::PBAR;
use binary_install::{Cache, Download};
use anyhow::Result;
use binary_install::Cache;
use std::path::Path;
use std::path::PathBuf;
use std::process::Command;
/// Execute `wasm-opt` over wasm binaries found in `out_dir`, downloading if
/// necessary into `cache`. Passes `args` to each invocation of `wasm-opt`.
pub fn run(
cache: &Cache,
out_dir: &Path,
args: &[String],
install_permitted: bool,
) -> Result<(), failure::Error> {
let wasm_opt = match find_wasm_opt(cache, install_permitted)? {
install::Status::Found(path) => path,
install::Status::CannotInstall => {
PBAR.info("Skipping wasm-opt as no downloading was requested");
return Ok(());
}
install::Status::PlatformNotSupported => {
PBAR.info("Skipping wasm-opt because it is not supported on this platform");
return Ok(());
}
pub fn run(cache: &Cache, out_dir: &Path, args: &[String], install_permitted: bool) -> Result<()> {
let wasm_opt_path = match find_wasm_opt(cache, install_permitted)? {
Some(path) => path,
// `find_wasm_opt` will have already logged a message about this, so we don't need to here.
None => return Ok(()),
};
let wasm_opt_path = wasm_opt.binary(&Tool::WasmOpt.to_string())?;
PBAR.info("Optimizing wasm binaries with `wasm-opt`...");
for file in out_dir.read_dir()? {
@ -54,25 +44,22 @@ pub fn run(
/// Returns `None` if a binary wasn't found in `PATH` and this platform doesn't
/// have precompiled binaries. Returns an error if we failed to download the
/// binary.
pub fn find_wasm_opt(
cache: &Cache,
install_permitted: bool,
) -> Result<install::Status, failure::Error> {
pub fn find_wasm_opt(cache: &Cache, install_permitted: bool) -> Result<Option<PathBuf>> {
// First attempt to look up in PATH. If found assume it works.
if let Ok(path) = which::which("wasm-opt") {
PBAR.info(&format!("found wasm-opt at {:?}", path));
return Ok(Some(path));
}
match path.as_path().parent() {
Some(path) => return Ok(install::Status::Found(Download::at(path))),
None => {}
match install::download_prebuilt(&install::Tool::WasmOpt, cache, "latest", install_permitted)? {
install::Status::Found(download) => Ok(Some(download.binary("bin/wasm-opt")?)),
install::Status::CannotInstall => {
PBAR.info("Skipping wasm-opt as no downloading was requested");
Ok(None)
}
install::Status::PlatformNotSupported => {
PBAR.info("Skipping wasm-opt because it is not supported on this platform");
Ok(None)
}
}
let version = "version_78";
Ok(install::download_prebuilt(
&install::Tool::WasmOpt,
cache,
version,
install_permitted,
)?)
}

@ -1,7 +1,7 @@
use crate::utils;
use assert_cmd::prelude::*;
use std::fs;
use std::path::Path;
use utils;
#[test]
fn build_in_non_crate_directory_doesnt_panic() {
@ -21,6 +21,36 @@ fn it_should_build_js_hello_world_example() {
fixture.wasm_pack().arg("build").assert().success();
}
#[test]
fn it_should_not_make_a_pkg_json_if_passed_no_pack() {
let fixture = utils::fixture::js_hello_world();
fixture
.wasm_pack()
.arg("build")
.arg("--no-pack")
.assert()
.success();
let pkg_path = fixture.path.join("pkg");
assert_eq!(pkg_path.join("package.json").exists(), false);
assert_eq!(pkg_path.join("README.md").exists(), false);
assert_eq!(pkg_path.join("licence").exists(), false);
}
#[test]
fn it_should_build_js_hello_world_example_with_custom_target_dir() {
let fixture = utils::fixture::js_hello_world();
fixture
.wasm_pack()
.arg("build")
.arg("--target-dir")
.arg("target2")
.arg("--all-features")
.arg("--offline")
.assert()
.success();
}
#[test]
fn it_should_build_crates_in_a_workspace() {
let fixture = utils::fixture::Fixture::new();

@ -1,6 +1,4 @@
use binary_install::Cache;
use tempfile;
use wasm_pack::install::{self, Tool};
use wasm_pack::install::{self, Arch, Os, Tool};
#[test]
#[cfg(any(
@ -10,7 +8,7 @@ use wasm_pack::install::{self, Tool};
))]
fn can_download_prebuilt_wasm_bindgen() {
let dir = tempfile::TempDir::new().unwrap();
let cache = Cache::at(dir.path());
let cache = binary_install::Cache::at(dir.path());
if let install::Status::Found(dl) =
install::download_prebuilt(&Tool::WasmBindgen, &cache, "0.2.74", true).unwrap()
{
@ -30,15 +28,13 @@ fn can_download_prebuilt_wasm_bindgen() {
fn downloading_prebuilt_wasm_bindgen_handles_http_errors() {
let dir = tempfile::TempDir::new().unwrap();
let bad_version = "0.2.74-some-trailing-version-stuff-that-does-not-exist";
let cache = Cache::at(dir.path());
let cache = binary_install::Cache::at(dir.path());
let result = install::download_prebuilt(&Tool::WasmBindgen, &cache, bad_version, true);
assert!(result.is_err());
let error = result.err().unwrap();
assert!(error.iter_chain().any(|e| e.to_string().contains("404")));
assert!(error
.iter_chain()
.any(|e| e.to_string().contains(bad_version)));
assert!(error.chain().any(|e| e.to_string().contains("404")));
assert!(error.chain().any(|e| e.to_string().contains(bad_version)));
}
#[test]
@ -49,7 +45,7 @@ fn downloading_prebuilt_wasm_bindgen_handles_http_errors() {
))]
fn can_download_prebuilt_cargo_generate() {
let dir = tempfile::TempDir::new().unwrap();
let cache = Cache::at(dir.path());
let cache = binary_install::Cache::at(dir.path());
if let install::Status::Found(dl) =
install::download_prebuilt(&Tool::CargoGenerate, &cache, "latest", true).unwrap()
{
@ -58,3 +54,56 @@ fn can_download_prebuilt_cargo_generate() {
assert!(false, "Download Failed");
}
}
#[test]
#[cfg(any(
all(target_os = "linux", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "aarch64"),
all(windows, target_arch = "x86_64"),
))]
fn can_download_prebuilt_wasm_opt() {
let dir = tempfile::TempDir::new().unwrap();
let cache = binary_install::Cache::at(dir.path());
if let install::Status::Found(dl) =
install::download_prebuilt(&Tool::WasmOpt, &cache, "latest", true).unwrap()
{
assert!(dl.binary("bin/wasm-opt").unwrap().is_file());
} else {
assert!(false, "Download Failed");
}
}
#[test]
fn all_latest_tool_download_urls_valid() {
let mut errors = Vec::new();
for tool in [Tool::CargoGenerate, Tool::WasmBindgen, Tool::WasmOpt] {
for arch in [Arch::X86_64, Arch::X86, Arch::AArch64] {
for os in [Os::Linux, Os::MacOS, Os::Windows] {
// For all valid tool, arch & os combinations,
// error out when any of them is a 404 or similar
if let Ok(url) = install::prebuilt_url_for(&tool, "0.2.82", &arch, &os) {
// Use HTTP HEAD instead of GET to avoid fetching lots of stuff
let res = ureq::head(&url).call().unwrap();
let status = res.status();
if 500 > status && status >= 400 {
errors.push(format!(
"Can't download URL {} for {} on {}: {}",
url,
arch,
os,
res.status()
));
}
}
}
}
}
if !errors.is_empty() {
panic!(
"Some URLs for prebuild tools were unavailable:\n{}",
errors.join("\n")
);
}
}

@ -1,5 +1,5 @@
use crate::utils;
use assert_cmd::prelude::*;
use utils;
#[test]
fn new_with_no_name_errors() {

@ -1,9 +1,9 @@
extern crate failure;
extern crate anyhow;
extern crate wasm_pack;
use std::fs;
use utils::{self, fixture};
use crate::utils::{self, fixture};
use wasm_pack::license;
use wasm_pack::manifest::CrateData;

@ -1,4 +1,4 @@
use utils::fixture;
use crate::utils::fixture;
use wasm_pack::lockfile::Lockfile;
use wasm_pack::manifest::CrateData;

@ -1,21 +1,18 @@
use crate::utils;
use assert_cmd::prelude::*;
use predicates::boolean::PredicateBooleanExt;
use predicates::prelude::predicate::str::contains;
use predicates::reflection::PredicateReflection;
use predicates::Predicate;
use utils;
use wasm_pack::emoji;
fn matches_info() -> impl Predicate<str> + PredicateReflection {
contains("[INFO]: Checking for the Wasm target...")
.and(contains("[INFO]: Compiling to Wasm..."))
contains(format!("[INFO]: {}Checking for the Wasm target...", emoji::TARGET))
.and(contains(format!("[INFO]: {}Compiling to Wasm...", emoji::CYCLONE)))
.and(contains("[INFO]: License key is set in Cargo.toml but no LICENSE file(s) were found; Please add the LICENSE file(s) to your project directory"))
.and(contains("[INFO]: Optimizing wasm binaries with `wasm-opt`..."))
.and(contains("[INFO]: :-) Done in "))
.and(contains("[INFO]: :-) Your wasm pkg is ready to publish at "))
}
fn matches_warn() -> impl Predicate<str> + PredicateReflection {
contains("[WARN]: :-) origin crate has no README")
.and(contains(format!("[INFO]: {} Done in ", emoji::SPARKLE)))
.and(contains(format!("[INFO]: {} Your wasm pkg is ready to publish at ", emoji::PACKAGE)))
}
fn matches_cargo() -> impl Predicate<str> + PredicateReflection {
@ -48,7 +45,7 @@ fn log_level_info() {
.assert()
.success()
.stdout("")
.stderr(matches_cargo().and(matches_warn()).and(matches_info()));
.stderr(matches_cargo().and(matches_info()));
}
#[test]
@ -63,11 +60,7 @@ fn log_level_warn() {
.assert()
.success()
.stdout("")
.stderr(
matches_cargo()
.and(matches_warn())
.and(matches_info().not()),
);
.stderr(matches_cargo().and(matches_info().not()));
}
#[test]
@ -82,9 +75,5 @@ fn log_level_error() {
.assert()
.success()
.stdout("")
.stderr(
matches_cargo()
.and(matches_warn().not())
.and(matches_info().not()),
);
.stderr(matches_cargo().and(matches_info().not()));
}

@ -1,15 +1,14 @@
extern crate anyhow;
extern crate assert_cmd;
extern crate failure;
extern crate predicates;
#[macro_use]
extern crate lazy_static;
extern crate predicates;
#[macro_use]
extern crate serde_derive;
extern crate binary_install;
extern crate serde_json;
#[macro_use]
extern crate serial_test;
extern crate structopt;
extern crate clap;
extern crate tempfile;
extern crate wasm_pack;

@ -1,11 +1,11 @@
use crate::utils::{self, fixture};
use assert_cmd::prelude::*;
use std::collections::{HashMap, HashSet};
use std::fs;
use std::path::PathBuf;
use utils::{self, fixture};
use wasm_pack::command::build::Target;
use wasm_pack::command::utils::get_crate_path;
use wasm_pack::{self, license, manifest};
use wasm_pack::{self, emoji, license, manifest};
#[test]
fn it_gets_the_crate_name_default_path() {
@ -94,7 +94,10 @@ fn it_creates_a_package_json_default_path() {
);
assert_eq!(pkg.main, "js_hello_world.js");
assert_eq!(pkg.types, "js_hello_world.d.ts");
assert_eq!(pkg.side_effects, false);
assert_eq!(
pkg.side_effects,
vec!["./js_hello_world.js", "./snippets/*"]
);
let actual_files: HashSet<String> = pkg.files.into_iter().collect();
let expected_files: HashSet<String> = [
@ -259,7 +262,7 @@ fn it_creates_a_package_json_with_correct_files_when_out_name_is_provided() {
);
assert_eq!(pkg.main, "index.js");
assert_eq!(pkg.types, "index.d.ts");
assert_eq!(pkg.side_effects, false);
assert_eq!(pkg.side_effects, vec!["./index.js", "./snippets/*"]);
let actual_files: HashSet<String> = pkg.files.into_iter().collect();
let expected_files: HashSet<String> =
@ -524,10 +527,7 @@ fn configure_wasm_bindgen_debug_incorrectly_is_error() {
.arg("build")
.arg("--dev")
.assert()
.failure()
.stderr(predicates::str::contains(
"package.metadata.wasm-pack.profile.dev.wasm-bindgen.debug",
));
.failure();
}
#[test]
@ -564,10 +564,11 @@ fn parse_crate_data_returns_unused_keys_in_cargo_toml() {
.arg("build")
.assert()
.success()
.stderr(predicates::str::contains(
"[WARN]: :-) \"package.metadata.wasm-pack.profile.production\" is an unknown key and will \
.stderr(predicates::str::contains(format!(
"[WARN]: {} \"package.metadata.wasm-pack.profile.production\" is an unknown key and will \
be ignored. Please check your Cargo.toml.",
));
emoji::WARN
)));
}
#[test]

@ -1,9 +1,12 @@
extern crate failure;
extern crate anyhow;
extern crate wasm_pack;
use std::fs;
use utils::{self, fixture};
use crate::utils::{self, fixture};
use assert_cmd::prelude::*;
use predicates::boolean::PredicateBooleanExt;
use wasm_pack::manifest::CrateData;
use wasm_pack::readme;
#[test]
@ -11,8 +14,9 @@ fn it_copies_a_readme_default_path() {
let fixture = fixture::js_hello_world();
let out_dir = fixture.path.join("pkg");
fs::create_dir(&out_dir).expect("should create pkg directory OK");
let crate_data = CrateData::new(&fixture.path, None).unwrap();
assert!(readme::copy_from_crate(&fixture.path, &out_dir).is_ok());
assert!(readme::copy_from_crate(&crate_data, &fixture.path, &out_dir).is_ok());
let crate_readme_path = fixture.path.join("README.md");
let pkg_readme_path = out_dir.join("README.md");
@ -32,12 +36,51 @@ fn it_copies_a_readme_default_path() {
#[test]
fn it_copies_a_readme_provided_path() {
let fixture = fixture::js_hello_world();
let fixture = fixture::Fixture::new();
fixture
.hello_world_src_lib()
.file(
"Cargo.toml",
r#"
[package]
authors = ["The wasm-pack developers"]
description = "so awesome rust+wasm package"
license = "WTFPL"
name = "js-hello-world"
readme = "docs/README.md"
repository = "https://github.com/rustwasm/wasm-pack.git"
version = "0.1.0"
[lib]
crate-type = ["cdylib"]
[dependencies]
# Note that this uses and `=` dependency because there are
# various tests which assert that the version of wasm
# bindgen downloaded is what we expect, and if `=` is
# removed then it will download whatever the newest version
# of wasm-bindgen is which may not be what's listed here.
wasm-bindgen = "=0.2.74"
[dev-dependencies]
wasm-bindgen-test = "0.3"
"#,
)
.file(
"docs/README.md",
r#"
# Fixture!
> an example rust -> wasm project
"#,
);
let crate_docs_dir = fixture.path.join("docs");
let out_dir = fixture.path.join("pkg");
fs::create_dir(&out_dir).expect("should create pkg directory OK");
let crate_data = CrateData::new(&fixture.path, None).unwrap();
assert!(readme::copy_from_crate(&fixture.path, &out_dir).is_ok());
let crate_readme_path = fixture.path.join("README.md");
assert!(readme::copy_from_crate(&crate_data, &fixture.path, &out_dir).is_ok());
let crate_readme_path = crate_docs_dir.join("README.md");
let pkg_readme_path = out_dir.join("README.md");
println!(
"wasm-pack: should have copied README.md from '{}' to '{}'",
@ -51,3 +94,42 @@ fn it_copies_a_readme_provided_path() {
let pkg_readme = utils::file::read_file(&pkg_readme_path).unwrap();
assert_eq!(crate_readme, pkg_readme);
}
#[test]
fn it_ignores_a_disabled_readme() {
let fixture = fixture::Fixture::new();
fixture
.hello_world_src_lib()
.file(
"Cargo.toml",
r#"
[package]
authors = ["The wasm-pack developers"]
description = "so awesome rust+wasm package"
name = "js-hello-world"
readme = false
repository = "https://github.com/rustwasm/wasm-pack.git"
version = "0.1.0"
[lib]
crate-type = ["cdylib"]
[dependencies]
# Note that this uses and `=` dependency because there are
# various tests which assert that the version of wasm
# bindgen downloaded is what we expect, and if `=` is
# removed then it will download whatever the newest version
# of wasm-bindgen is which may not be what's listed here.
wasm-bindgen = "=0.2.74"
[dev-dependencies]
wasm-bindgen-test = "0.3"
"#,
)
.license()
.wasm_pack()
.arg("build")
.assert()
.success()
.stderr(predicates::str::contains("origin crate has no README").not());
}

@ -1,7 +1,7 @@
use crate::utils::fixture;
use assert_cmd::prelude::*;
use predicates::prelude::*;
use std::env;
use utils::fixture;
#[test]
fn it_can_run_node_tests() {
@ -33,6 +33,7 @@ fn it_can_run_tests_with_different_wbg_test_and_wbg_versions() {
#[cfg(any(
all(target_os = "linux", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "aarch64"),
all(target_os = "windows", target_arch = "x86"),
all(target_os = "windows", target_arch = "x86_64")
))]
@ -44,6 +45,7 @@ fn it_can_run_browser_tests() {
all(target_os = "linux", target_arch = "x86"),
all(target_os = "linux", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "aarch64"),
all(target_os = "windows", target_arch = "x86"),
all(target_os = "windows", target_arch = "x86_64")
));
@ -104,6 +106,7 @@ fn it_can_run_failing_tests() {
all(target_os = "linux", target_arch = "x86"),
all(target_os = "linux", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "aarch64"),
all(target_os = "windows", target_arch = "x86"),
all(target_os = "windows", target_arch = "x86_64")
))]

@ -2,9 +2,9 @@ use std::fs::File;
use std::io::Read;
use std::path::Path;
use failure::Error;
use anyhow::Result;
pub fn read_file(path: &Path) -> Result<String, Error> {
pub fn read_file(path: &Path) -> Result<String> {
let mut file = File::open(path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;

@ -1,4 +1,5 @@
use binary_install::Cache;
use lazy_static::lazy_static;
use std::env;
use std::fs;
use std::mem::ManuallyDrop;
@ -321,7 +322,9 @@ impl Fixture {
}
pub fn cache(&self) -> Cache {
Cache::at(&self.cache_dir())
let cache_dir = self.cache_dir();
fs::create_dir_all(&cache_dir).unwrap();
Cache::at(&cache_dir)
}
/// The `step_install_wasm_bindgen` and `step_run_wasm_bindgen` steps only
@ -348,6 +351,10 @@ impl Fixture {
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap();
cmd.current_dir(&self.path);
cmd.env("WASM_PACK_CACHE", self.cache_dir());
// Some of the tests assume that Cargo's output does not contain colors.
cmd.env_remove("CARGO_TERM_COLOR");
cmd
}

@ -2,7 +2,7 @@ use std::io::prelude::*;
use std::path::Path;
use std::{collections::HashMap, fs::File};
use failure::Error;
use anyhow::Result;
use serde_json;
#[derive(Deserialize)]
@ -23,8 +23,8 @@ pub struct NpmPackage {
pub browser: String,
#[serde(default = "default_none")]
pub types: String,
#[serde(default = "default_false", rename = "sideEffects")]
pub side_effects: bool,
#[serde(default = "Vec::new", rename = "sideEffects")]
pub side_effects: Vec<String>,
pub homepage: Option<String>,
pub keywords: Option<Vec<String>>,
pub dependencies: Option<HashMap<String, String>>,
@ -34,10 +34,6 @@ fn default_none() -> String {
"".to_string()
}
fn default_false() -> bool {
false
}
#[derive(Deserialize)]
pub struct Repository {
#[serde(rename = "type")]
@ -45,7 +41,7 @@ pub struct Repository {
pub url: String,
}
pub fn read_package_json(path: &Path, out_dir: &Path) -> Result<NpmPackage, Error> {
pub fn read_package_json(path: &Path, out_dir: &Path) -> Result<NpmPackage> {
let manifest_path = path.join(out_dir).join("package.json");
let mut pkg_file = File::open(manifest_path)?;
let mut pkg_contents = String::new();
@ -54,7 +50,7 @@ pub fn read_package_json(path: &Path, out_dir: &Path) -> Result<NpmPackage, Erro
Ok(serde_json::from_str(&pkg_contents)?)
}
pub fn create_wbg_package_json(out_dir: &Path, contents: &str) -> Result<(), Error> {
pub fn create_wbg_package_json(out_dir: &Path, contents: &str) -> Result<()> {
let manifest_path = out_dir.join("package.json");
Ok(std::fs::write(manifest_path, contents)?)
}

@ -1,6 +1,6 @@
use crate::utils;
use assert_cmd::prelude::*;
use predicates::prelude::*;
use utils;
#[test]
fn off_in_dev() {

@ -1,5 +1,5 @@
use crate::utils::fixture;
use binary_install::Cache;
use utils::fixture;
use wasm_pack::test::webdriver;
#[test]
@ -20,6 +20,7 @@ fn can_install_chromedriver() {
all(target_os = "linux", target_arch = "x86"),
all(target_os = "linux", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "aarch64"),
all(target_os = "windows", target_arch = "x86"),
all(target_os = "windows", target_arch = "x86_64")
))]

Loading…
Cancel
Save