diff --git a/.appveyor.yml b/.appveyor.yml
index f50ea0e6..b14e7e60 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -19,23 +19,25 @@ test_script:
before_deploy:
- ps: |
- $NAME = "wasm-pack-${env:APPVEYOR_REPO_TAG_NAME}-${env:TARGET}"
+ $NAME = "wasm-pack-${env:APPVEYOR_REPO_TAG_NAME}-x86_64-pc-windows-msvc"
New-Item -Path $NAME -ItemType directory
Copy-Item target/release/wasm-pack.exe "${NAME}/"
+ Copy-Item target/release/wasm-pack.exe wasm-pack-init.exe
Copy-Item LICENSE-MIT "${NAME}/"
Copy-Item LICENSE-APACHE "${NAME}/"
Copy-Item README.md "${NAME}/"
7z a -ttar "${NAME}.tar" "${NAME}"
7z a "${NAME}.tar.gz" "${NAME}.tar"
Push-AppveyorArtifact "${NAME}.tar.gz"
+ Push-AppveyorArtifact wasm-pack-init.exe
deploy:
- artifact: /.*\.tar.gz/
+ artifact: /.*\.tar.gz/, /.*\.exe/
description: 'Appveyor Automated Release'
provider: GitHub
draft: false
prerelease: false
- autho_token:
+ auth_token:
secure: iHsRUqwGf/Zh7OuYpHOWQL8buaOL+c8/6kXLRly8V2j0LCUo7CcDs0NxQ0vl2bhZ
on:
appveyor_repo_tag: true
diff --git a/.gitignore b/.gitignore
index 4b2ee66a..ea6c5a6e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ target/
tests/.crates.toml
tests/bin
wasm-pack.log
+/build-installer
diff --git a/.travis.yml b/.travis.yml
index 5b143b2f..977b9d5f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,6 +14,9 @@ cache:
directories:
- /home/travis/.cargo
+GH_TOKEN: &GH_TOKEN
+ secure: fx0rR5Ii1KcsydexE6QpkDbqItNdj3Lt6L5yFZaKKB/ejw9M555NkXA+0GZqV0sLZ54qfR8zTaXAf6eBFKgcG9etaCl7vTXqsvDrlssth82oki1zufP39uuoOy4WgFq8OfACOtUq7opDAgYmpaGzlFiny+c5j7asGwDtAU1Fc3JeJsvAnxHKg9+0spXFD6kBQd5CWpqDXv2rLFK0b8IM2fHAzd0PiJZQWqz//2Cj/r9rTiewtIzqigctAfOgFwYoQvfdM+0mKb4pefG+zXEGfxxQr4r5hqZ6UMO7hto3Jnm9LRjNR8dNaDQCqQ0bkdLTAMTC3nV/gZPM679yQU3KHueVjg9pleNzuKnuBgYmH9+BrlG1dW68kqA+6Xh+wIJYrLuagWhJDlCtiU6PM5QAbFg3mabPIBG3M2IHTrOVATme+iW5vpROARhgjbQEF235DyvZaT+Tml3+PY+PfcRax2DVUhvGQViv4tzppbT0PjjBlEbGct49cFLGdqZIJBiVrYW24I2QkENTnUgZsFIBuJlVCBHZwZlLo9ldVvu4XTMKw65z42zoTzobjtbC1QPEZPiaJXSxC7W569fqL/ORXwGToFk6rQjXwEqDP2okGiusR75LXrZD6qFibNpqeypRFtqOzntsOfTUGrlaN1yTt/6dz0V0j9uI7a9/CHVcblI=
+
DEPLOY_TO_GITHUB: &DEPLOY_TO_GITHUB
before_deploy:
- git config --local user.name "Ashley Williams"
@@ -25,14 +28,11 @@ DEPLOY_TO_GITHUB: &DEPLOY_TO_GITHUB
- tar czvf $name.tar.gz $name
deploy:
provider: releases
- api_key:
- secure: fx0rR5Ii1KcsydexE6QpkDbqItNdj3Lt6L5yFZaKKB/ejw9M555NkXA+0GZqV0sLZ54qfR8zTaXAf6eBFKgcG9etaCl7vTXqsvDrlssth82oki1zufP39uuoOy4WgFq8OfACOtUq7opDAgYmpaGzlFiny+c5j7asGwDtAU1Fc3JeJsvAnxHKg9+0spXFD6kBQd5CWpqDXv2rLFK0b8IM2fHAzd0PiJZQWqz//2Cj/r9rTiewtIzqigctAfOgFwYoQvfdM+0mKb4pefG+zXEGfxxQr4r5hqZ6UMO7hto3Jnm9LRjNR8dNaDQCqQ0bkdLTAMTC3nV/gZPM679yQU3KHueVjg9pleNzuKnuBgYmH9+BrlG1dW68kqA+6Xh+wIJYrLuagWhJDlCtiU6PM5QAbFg3mabPIBG3M2IHTrOVATme+iW5vpROARhgjbQEF235DyvZaT+Tml3+PY+PfcRax2DVUhvGQViv4tzppbT0PjjBlEbGct49cFLGdqZIJBiVrYW24I2QkENTnUgZsFIBuJlVCBHZwZlLo9ldVvu4XTMKw65z42zoTzobjtbC1QPEZPiaJXSxC7W569fqL/ORXwGToFk6rQjXwEqDP2okGiusR75LXrZD6qFibNpqeypRFtqOzntsOfTUGrlaN1yTt/6dz0V0j9uI7a9/CHVcblI=
- file_glob: true
+ api_key: *GH_TOKEN
file: wasm-pack-$TRAVIS_TAG-$TARGET.tar.gz
skip_cleanup: true
on:
branch: master
- condition: $DEPLOY = 1
tags: true
matrix:
@@ -59,18 +59,20 @@ matrix:
- (test -x $HOME/.cargo/bin/mdbook || cargo install --vers "^0.1" mdbook)
- cargo install-update -a
script:
- - cd docs && mdbook build
+ - (cd docs && mdbook build)
+ - rustc ./docs/installer/build-installer.rs
+ - ./build-installer
deploy:
provider: pages
skip-cleanup: true
- github-token: $GITHUB_TOKEN
+ github-token: *GH_TOKEN
local-dir: docs/book
keep-history: false
on:
branch: master
# dist linux binary
- - env: JOB=dist-linux TARGET=x86_64-unknown-linux-musl DEPLOY=1
+ - env: JOB=dist-linux TARGET=x86_64-unknown-linux-musl
rust: nightly
before_script: rustup target add $TARGET
script: cargo build --release --target $TARGET --locked --features vendored-openssl
@@ -81,7 +83,7 @@ matrix:
<<: *DEPLOY_TO_GITHUB
# dist OSX binary
- - env: JOB=dist-osx MACOSX_DEPLOYMENT_TARGET=10.7 DEPLOY=1 TARGET=x86_64-apple-darwin
+ - env: JOB=dist-osx MACOSX_DEPLOYMENT_TARGET=10.7 TARGET=x86_64-apple-darwin
os: osx
rust: nightly
script: cargo build --release --target $TARGET --locked
diff --git a/Cargo.lock b/Cargo.lock
index 8aa26c7d..2b06be94 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -900,6 +900,7 @@ dependencies = [
name = "wasm-pack"
version = "0.4.2"
dependencies = [
+ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"console 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"copy_dir 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"curl 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/Cargo.toml b/Cargo.toml
index ac1d24fe..1113f156 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,6 +9,7 @@ readme = "README.md"
categories = ["wasm"]
[dependencies]
+atty = "0.2.11"
console = "0.6.1"
curl = "0.4.13"
failure = "0.1.2"
diff --git a/docs/installer/build-installer.rs b/docs/installer/build-installer.rs
new file mode 100644
index 00000000..a5aa5995
--- /dev/null
+++ b/docs/installer/build-installer.rs
@@ -0,0 +1,30 @@
+use std::fs;
+
+fn main() {
+ fs::create_dir_all("docs/book/installer").unwrap();
+ fs::copy(
+ "docs/installer/wasm-pack.js",
+ "docs/book/installer/wasm-pack.js",
+ ).unwrap();
+ let index = fs::read_to_string("docs/installer/index.html").unwrap();
+ fs::write(
+ "docs/book/installer/index.html",
+ fixup(&index),
+ ).unwrap();
+
+ let init = fs::read_to_string("docs/installer/init.sh").unwrap();
+ fs::write(
+ "docs/book/installer/init.sh",
+ fixup(&init),
+ ).unwrap();
+}
+
+fn fixup(input: &str) -> String {
+ let manifest = fs::read_to_string("Cargo.toml").unwrap();
+ let version = manifest.lines()
+ .find(|line| line.starts_with("version ="))
+ .unwrap();
+ let version = &version[version.find('"').unwrap() + 1..version.rfind('"').unwrap()];
+
+ input.replace("$VERSION", &format!("v{}", version))
+}
diff --git a/docs/installer/index.html b/docs/installer/index.html
new file mode 100644
index 00000000..f4463b28
--- /dev/null
+++ b/docs/installer/index.html
@@ -0,0 +1,106 @@
+
+
+
+
+ wasm-pack
+
+
+
+
+
+ Install wasm-pack! A tool with a blurb here.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/installer/init.sh b/docs/installer/init.sh
new file mode 100644
index 00000000..247a1ba6
--- /dev/null
+++ b/docs/installer/init.sh
@@ -0,0 +1,180 @@
+#!/bin/bash
+# Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+# file at the top-level directory of this distribution and at
+# http://rust-lang.org/COPYRIGHT.
+#
+# Licensed under the Apache License, Version 2.0 or the MIT license
+# , at your
+# option. This file may not be copied, modified, or distributed
+# except according to those terms.
+
+# This is just a little script that can be downloaded from the internet to
+# install wasm-pack. It just does platform detection, downloads the installer
+# and runs it.
+
+set -u
+
+UPDATE_ROOT="https://github.com/rustwasm/wasm-pack/releases/download/$VERSION"
+
+main() {
+ downloader --check
+ need_cmd uname
+ need_cmd mktemp
+ need_cmd chmod
+ need_cmd mkdir
+ need_cmd rm
+ need_cmd rmdir
+ need_cmd tar
+ need_cmd which
+ need_cmd dirname
+
+ get_architecture || return 1
+ local _arch="$RETVAL"
+ assert_nz "$_arch" "arch"
+
+ local _ext=""
+ case "$_arch" in
+ *windows*)
+ _ext=".exe"
+ ;;
+ esac
+
+ which rustup > /dev/null 2>&1
+ need_ok "failed to find Rust installation, is rustup installed?"
+ local _rustup=`which rustup`
+ local _tardir="wasm-pack-$VERSION-${_arch}"
+ local _url="$UPDATE_ROOT/${_tardir}.tar.gz"
+ local _dir="$(mktemp -d 2>/dev/null || ensure mktemp -d -t wasm-pack)"
+ local _file="$_dir/input.tar.gz"
+ local _wasmpack="$_dir/wasm-pack$_ext"
+ local _wasmpackinit="$_dir/wasm-pack-init$_ext"
+
+ printf '%s\n' 'info: downloading wasm-pack' 1>&2
+
+ ensure mkdir -p "$_dir"
+ downloader "$_url" "$_file"
+ if [ $? != 0 ]; then
+ say "failed to download $_url"
+ say "this may be a standard network error, but it may also indicate"
+ say "that wasm-pack's release process is not working. When in doubt"
+ say "please feel free to open an issue!"
+ exit 1
+ fi
+ ensure tar xf "$_file" --strip-components 1 -C "$_dir"
+ mv "$_wasmpack" "$_wasmpackinit"
+ "$_wasmpackinit" "$@"
+ local _retval=$?
+
+ ignore rm -rf "$_dir"
+
+ return "$_retval"
+}
+
+get_architecture() {
+ local _ostype="$(uname -s)"
+ local _cputype="$(uname -m)"
+
+ if [ "$_ostype" = Darwin -a "$_cputype" = i386 ]; then
+ # Darwin `uname -s` lies
+ if sysctl hw.optional.x86_64 | grep -q ': 1'; then
+ local _cputype=x86_64
+ fi
+ fi
+
+ case "$_ostype" in
+ Linux)
+ local _ostype=unknown-linux-musl
+ ;;
+
+ Darwin)
+ local _ostype=apple-darwin
+ ;;
+
+ MINGW* | MSYS* | CYGWIN*)
+ local _ostype=pc-windows-msvc
+ ;;
+
+ *)
+ err "no precompiled binaries available for OS: $_ostype"
+ ;;
+ esac
+
+ case "$_cputype" in
+ x86_64 | x86-64 | x64 | amd64)
+ local _cputype=x86_64
+ ;;
+ *)
+ err "no precompiled binaries available for CPU architecture: $_cputype"
+
+ esac
+
+ local _arch="$_cputype-$_ostype"
+
+ RETVAL="$_arch"
+}
+
+say() {
+ echo "wasm-pack-init: $1"
+}
+
+err() {
+ say "$1" >&2
+ exit 1
+}
+
+need_cmd() {
+ if ! check_cmd "$1"
+ then err "need '$1' (command not found)"
+ fi
+}
+
+check_cmd() {
+ command -v "$1" > /dev/null 2>&1
+ return $?
+}
+
+need_ok() {
+ if [ $? != 0 ]; then err "$1"; fi
+}
+
+assert_nz() {
+ if [ -z "$1" ]; then err "assert_nz $2"; fi
+}
+
+# Run a command that should never fail. If the command fails execution
+# will immediately terminate with an error showing the failing
+# command.
+ensure() {
+ "$@"
+ need_ok "command failed: $*"
+}
+
+# This is just for indicating that commands' results are being
+# intentionally ignored. Usually, because it's being executed
+# as part of error handling.
+ignore() {
+ "$@"
+}
+
+# This wraps curl or wget. Try curl first, if not installed,
+# use wget instead.
+downloader() {
+ if check_cmd curl
+ then _dld=curl
+ elif check_cmd wget
+ then _dld=wget
+ else _dld='curl or wget' # to be used in error message of need_cmd
+ fi
+
+ if [ "$1" = --check ]
+ then need_cmd "$_dld"
+ elif [ "$_dld" = curl ]
+ then curl -sSfL "$1" -o "$2"
+ elif [ "$_dld" = wget ]
+ then wget "$1" -O "$2"
+ else err "Unknown downloader" # should not reach here
+ fi
+}
+
+main "$@" || exit 1
diff --git a/docs/installer/wasm-pack.js b/docs/installer/wasm-pack.js
new file mode 100644
index 00000000..5d87b703
--- /dev/null
+++ b/docs/installer/wasm-pack.js
@@ -0,0 +1,92 @@
+var platforms = ["default", "unknown", "win64", "unix"];
+var platform_override = null;
+
+function detect_platform() {
+ "use strict";
+
+ if (platform_override !== null) {
+ return platforms[platform_override];
+ }
+
+ var os = "unknown";
+
+ if (navigator.platform == "Linux x86_64") {os = "unix";}
+ if (navigator.platform == "Linux i686") {os = "unix";}
+ if (navigator.platform == "Linux i686 on x86_64") {os = "unix";}
+ if (navigator.platform == "Linux aarch64") {os = "unix";}
+ if (navigator.platform == "Linux armv6l") {os = "unix";}
+ if (navigator.platform == "Linux armv7l") {os = "unix";}
+ if (navigator.platform == "Linux armv8l") {os = "unix";}
+ if (navigator.platform == "Linux ppc64") {os = "unix";}
+ if (navigator.platform == "Linux mips") {os = "unix";}
+ if (navigator.platform == "Linux mips64") {os = "unix";}
+ if (navigator.platform == "Mac") {os = "unix";}
+ // if (navigator.platform == "Win32") {os = "win32";}
+ if (navigator.platform == "Win64" ||
+ navigator.userAgent.indexOf("WOW64") != -1 ||
+ navigator.userAgent.indexOf("Win64") != -1) { os = "win64"; }
+ if (navigator.platform == "FreeBSD x86_64") {os = "unix";}
+ if (navigator.platform == "FreeBSD amd64") {os = "unix";}
+ if (navigator.platform == "NetBSD x86_64") {os = "unix";}
+ if (navigator.platform == "NetBSD amd64") {os = "unix";}
+
+ // I wish I knew by now, but I don't. Try harder.
+ if (os == "unknown") {
+ // if (navigator.appVersion.indexOf("Win")!=-1) {os = "win32";}
+ if (navigator.appVersion.indexOf("Mac")!=-1) {os = "unix";}
+ // rust-www/#692 - FreeBSD epiphany!
+ if (navigator.appVersion.indexOf("FreeBSD")!=-1) {os = "unix";}
+ }
+
+ // Firefox Quantum likes to hide platform and appVersion but oscpu works
+ if (navigator.oscpu) {
+ // if (navigator.oscpu.indexOf("Win32")!=-1) {os = "win32";}
+ if (navigator.oscpu.indexOf("Win64")!=-1) {os = "win64";}
+ if (navigator.oscpu.indexOf("Mac")!=-1) {os = "unix";}
+ if (navigator.oscpu.indexOf("Linux")!=-1) {os = "unix";}
+ if (navigator.oscpu.indexOf("FreeBSD")!=-1) {os = "unix";}
+ if (navigator.oscpu.indexOf("NetBSD")!=-1) {os = "unix";}
+ }
+
+ return os;
+}
+
+function adjust_for_platform() {
+ "use strict";
+
+ var platform = detect_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')) {
+ 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");
+ nav_plat.textContent = navigator.platform;
+ nav_app.textContent = navigator.appVersion;
+}
+
+(function () {
+ adjust_for_platform();
+ set_up_default_platform_buttons();
+ fill_in_bug_report_values();
+}());
diff --git a/src/installer.rs b/src/installer.rs
new file mode 100644
index 00000000..d393e036
--- /dev/null
+++ b/src/installer.rs
@@ -0,0 +1,125 @@
+//! Self-installation of `wasm-pack`
+//!
+//! This module contains one public function which will self-install the
+//! currently running executable as `wasm-pack`. Our goal is to install this in
+//! a place that's already in `PATH`, ideally in an idiomatic location. To that
+//! end we place `wasm-pack` next to the `rustup` executable in `PATH`.
+//!
+//! This installer is run directly (probably by clicking on it) on Windows,
+//! meaning it will pop up a console (as we're a console app). Output goes to
+//! the console and users interact with it through the console. On Unix this is
+//! intended to be run from a shell script (docs/installer/init.sh) which is
+//! downloaded via curl/sh, and then the shell script downloads this executable
+//! and runs it.
+//!
+//! This may get more complicated over time (self upates anyone?) but for now
+//! it's pretty simple! We're largely just moving over our currently running
+//! executable to a different path.
+
+use std::env;
+use std::fs;
+use std::io;
+use std::path::Path;
+use std::process;
+
+use atty;
+use failure::{Error, ResultExt};
+
+pub fn install() -> ! {
+ if let Err(e) = do_install() {
+ eprintln!("{}", e);
+ for cause in e.iter_causes() {
+ eprintln!("Caused by: {}", cause);
+ }
+ }
+
+ // On Windows we likely popped up a console for the installation. If we were
+ // to exit here immediately then the user wouldn't see any error that
+ // happened above or any successful message. Let's wait for them to say
+ // they've read everything and then continue.
+ if cfg!(windows) {
+ println!("Press enter to close this window...");
+ let mut line = String::new();
+ drop(io::stdin().read_line(&mut line));
+ }
+
+ process::exit(0);
+}
+
+fn do_install() -> Result<(), Error> {
+ // Find `rustup.exe` in PATH, we'll be using its installation directory as
+ // our installation directory.
+ let path = env::var_os("PATH").unwrap_or_default();
+ let rustup = env::split_paths(&path)
+ .map(|p| p.join("rustup").with_extension(env::consts::EXE_EXTENSION))
+ .find(|p| p.exists());
+ let rustup = match rustup {
+ Some(path) => path,
+ None => {
+ bail!(
+ "failed to find an installation of `rustup` in `PATH`, \
+ is rustup already installed?"
+ );
+ }
+ };
+ let installation_dir = match rustup.parent() {
+ Some(parent) => parent,
+ None => bail!("can't install when `rustup` is at the root of the filesystem"),
+ };
+ let destination = installation_dir
+ .join("wasm-pack")
+ .with_extension(env::consts::EXE_EXTENSION);
+
+ if destination.exists() {
+ confirm_can_overwrite(&destination)?;
+ }
+
+ // Our relatively simple install step!
+ let me = env::current_exe()?;
+ fs::copy(&me, &destination)
+ .with_context(|_| format!("failed to copy executable to `{}`", destination.display()))?;
+ println!(
+ "info: successfully installed wasm-pack to `{}`",
+ destination.display()
+ );
+
+ // ... and that's it!
+
+ Ok(())
+}
+
+fn confirm_can_overwrite(dst: &Path) -> Result<(), Error> {
+ // If the `-f` argument was passed, we can always overwrite everything.
+ if env::args().any(|arg| arg == "-f") {
+ return Ok(());
+ }
+
+ // If we're not attached to a TTY then we can't get user input, so there's
+ // nothing to do except inform the user about the `-f` flag.
+ if !atty::is(atty::Stream::Stdin) {
+ bail!(
+ "existing wasm-pack installation found at `{}`, pass `-f` to \
+ force installation over this file, otherwise aborting \
+ installation now",
+ dst.display()
+ );
+ }
+
+ // It looks like we're at an interactive prompt, so ask the user if they'd
+ // like to overwrite the previous installation.
+ eprintln!(
+ "info: existing wasm-pack installation found at `{}`",
+ dst.display()
+ );
+ eprint!("info: would you like to overwrite this file? [y/N]: ");
+ let mut line = String::new();
+ io::stdin()
+ .read_line(&mut line)
+ .with_context(|_| "failed to read stdin")?;
+
+ if line.starts_with("y") || line.starts_with("Y") {
+ return Ok(());
+ }
+
+ bail!("aborting installation");
+}
diff --git a/src/main.rs b/src/main.rs
index 39b56a35..9c83123b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,31 +1,42 @@
+extern crate atty;
+#[macro_use]
extern crate failure;
#[macro_use]
extern crate human_panic;
extern crate structopt;
extern crate wasm_pack;
-use failure::Fail;
use std::env;
use structopt::StructOpt;
-use wasm_pack::{command::run_wasm_pack, error::Error, logger, Cli};
+use wasm_pack::{command::run_wasm_pack, logger, Cli};
+
+mod installer;
fn main() {
setup_panic!();
if let Err(e) = run() {
eprintln!("{}", e);
- for cause in Fail::iter_causes(&e) {
+ for cause in e.iter_causes() {
eprintln!("Caused by: {}", cause);
}
::std::process::exit(1);
}
}
-fn run() -> Result<(), Error> {
+fn run() -> Result<(), failure::Error> {
// Deprecate `init`
if let Some("init") = env::args().nth(1).as_ref().map(|arg| arg.as_str()) {
println!("wasm-pack init is deprecated, consider using wasm-pack build");
}
+ if let Ok(me) = env::current_exe() {
+ // If we're actually running as the installer then execute our
+ // self-installation, otherwise just continue as usual.
+ if me.file_stem().and_then(|s| s.to_str()) == Some("wasm-pack-init") {
+ installer::install();
+ }
+ }
+
let args = Cli::from_args();
let log = logger::new(&args.cmd, args.verbosity)?;
run_wasm_pack(args.cmd, &log)?;