Last active
June 16, 2020 10:09
-
-
Save dzil123/53a90510c49562499d65bd5f041b0ece to your computer and use it in GitHub Desktop.
Helper to create and build projects with https://github.com/yewstack/yew as an alternative to wasm-pack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/bash | |
# uses bash specific features | |
# Formatted with 'shfmt -i 4 -w file.sh' | |
# set -e | |
# set -u | |
set -o pipefail | |
shopt -s lastpipe | |
cargo_bin=$(realpath ${CARGO_INSTALL_ROOT:-${CARGO_HOME:-~/.cargo}/bin}) | |
export PATH="$PATH:$cargo_bin" | |
function fail() { | |
echo $@ >&2 | |
exit 1 | |
} | |
function cargo_install_fail() { | |
echo "" >&2 | |
echo "Unable to access '$1'!" >&2 | |
echo "Please ensure $cargo_bin is where cargo installs executables" >&2 | |
echo "Or otherwise add '$1' to PATH" >&2 | |
exit 1 | |
} | |
function ensure_deps_installed() { | |
cargo add --version >/dev/null 2>&1 || cargo_install_fail "cargo add" | |
wasm-bindgen --version >/dev/null 2>&1 || cargo_install_fail "wasm-bindgen" | |
} | |
# Install dependencies for Arch Linux and rustup | |
function install() { | |
sudo pacman -Syu --needed binaryen npm jq rustup | |
rustup toolchain add stable | |
rustup target add wasm32-unknown-unknown | |
rustup update | |
cargo install wasm-bindgen-cli cargo-edit | |
} | |
#src rust source | |
#static html/js/css source | |
#-- ignored -- | |
#target compiled rust | |
#dist compiled html/js/css wasm | |
function new() { | |
ensure_deps_installed | |
cargo new -- "$1" | |
mkdir --parents "$1" | |
cd "$1" | |
# to generate: | |
# tar -czv .cargo/config .gitignore src/lib.rs static/index.html | base64 | |
base64 -d <<EOF | tar xz | |
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 | |
EOF | |
# Last major release as of 06/15/2020 | |
cargo add --sort [email protected] [email protected] [email protected] [email protected] | |
cat >>Cargo.toml <<EOF | |
[profile.release] | |
panic = 'abort' | |
codegen-units = 1 | |
opt-level = 'z' | |
lto = true | |
EOF | |
# package name != "$1" because "$1" could have subdirectories | |
pkg_name=$(grep Cargo.toml -e "^name" | cut -d'"' -f2 | head --lines 1) | |
cat >src/main.rs <<EOF | |
fn main() { | |
yew::start_app::<$pkg_name::Model>(); | |
} | |
EOF | |
git add . | |
git commit -m"Initial commit" | |
} | |
# Usage: `find_up filename` | |
# Recursively looks in current and parent directories | |
# until it finds the file. | |
# If found, echo the directory and exit 0. | |
# If not found, exit 1. | |
function find_up() { | |
dir=$(pwd) | |
while [[ $dir != / ]]; do | |
find "$dir" -maxdepth 1 -mindepth 1 -name "$1" | read | |
if [ $? -eq 0 ]; then | |
echo $dir | |
return 0 | |
fi | |
dir="$(realpath -s "$dir"/..)" | |
done | |
return 1 | |
} | |
function copy() { | |
cp --verbose "$1" "$2" | |
} | |
# Usage: `minify_whatever source dest` | |
function minify_html() { | |
# todo: uhhhhhh | |
copy $@ | |
} | |
function minify_js() { | |
( | |
npx --version >/dev/null 2>&1 && | |
npx terser -c -m module=true,reserved=['init'] \ | |
-o "$2" -- "$1" | |
) || copy $@ | |
} | |
function minify_wasm() { | |
( | |
wasm-opt --version >/dev/null 2>&1 && | |
wasm-opt "$1" -Oz --strip-debug --output "$2" | |
) || copy $@ | |
} | |
function cargo_build_debug() { | |
# run once to get good user output, then run again to get json output | |
cargo build --target wasm32-unknown-unknown $@ >&2 && | |
cargo build --target wasm32-unknown-unknown --message-format json $@ 2>/dev/null | |
} | |
function cargo_build_release() { | |
cargo_build_debug --release $@ | |
} | |
# Usage: `wasm-bindgen_mode compiled.wasm temp_dir [extras...]` | |
function wasm_bindgen_release() { | |
source=$1 | |
dest=$2 | |
shift 2 | |
mkdir --parents "$dest" | |
wasm-bindgen $@ --target web --no-typescript --out-dir "$dest" --out-name wasm "$source" | |
} | |
function wasm_bindgen_debug() { | |
wasm_bindgen_release $@ --keep-debug --debug | |
} | |
function parse_location() { | |
# TARGET="$SRCDIR/target/wasm32-unknown-unknown/{profile}/{name}.wasm" | |
# jq --raw-output 'select(.target?.kind?[0] == "bin") | .target.name' | tail --lines 1 | |
# todo: catch {"reason":"build-finished","success":false} ? | |
jq --raw-output 'select(.target?.kind?[0] == "bin") | .executable' | tail --lines 1 | |
} | |
function cd_srcdir() { | |
srcdir=$(find_up Cargo.toml) | |
if [ $? -ne 0 ]; then | |
fail "Could not find source directory" | |
fi | |
cd "$srcdir" | |
} | |
# Usage: `build` for debug | |
# `build 1` for release | |
function build() { | |
ensure_deps_installed | |
cd_srcdir | |
# mode == 0 -> debug, else release | |
[[ $1 -eq 0 ]] | |
mode=$? | |
( | |
if ((mode == 0)); then | |
cargo_build_debug | |
else | |
cargo_build_release | |
fi | |
) | parse_location | read binary || fail "Cargo build failed" | |
echo "Binary at $binary" | |
wasm_bindgen_dir="$(dirname "$binary")/wasm_bindgen_temp/" | |
mkdir --parents dist | |
# todo: copy arbitrary static/ files with correct minifiers | |
if ((mode == 0)); then | |
wasm_bindgen_debug "$binary" ./dist | |
copy ./static/index.html ./dist/index.html | |
else | |
wasm_bindgen_release "$binary" "$wasm_bindgen_dir" | |
minify_html ./static/index.html ./dist/index.html | |
minify_js "$wasm_bindgen_dir/wasm.js" ./dist/wasm.js | |
minify_wasm "$wasm_bindgen_dir/wasm_bg.wasm" ./dist/wasm_bg.wasm | |
fi | |
} | |
function clean() { | |
cd_srcdir | |
rm -fdrv dist | |
} | |
function usage() { | |
echo "Usage: $programname build|run [-r|--release]" | |
echo " $programname clean" | |
echo " $programname new <path>" | |
echo " $programname install # Arch-only" | |
return 1 | |
} | |
function build_cmd() { | |
release=0 | |
case $1 in | |
"r" | "-r" | "--release") | |
release=1 | |
;; | |
"") ;; | |
*) | |
usage | |
return | |
;; | |
esac | |
build $release | |
} | |
function run() { | |
build_cmd $@ && | |
# todo: port? | |
python -m http.server --directory ./dist | |
} | |
function main() { | |
programname=$(basename "$0") | |
subcommand=$1 | |
shift | |
case $subcommand in | |
"b" | "build") | |
build_cmd $@ | |
;; | |
"r" | "run") | |
run $@ | |
;; | |
"n" | "new") | |
new $@ | |
;; | |
"install") | |
install | |
;; | |
"c" | "clean") | |
clean | |
;; | |
"" | "help" | "-h" | "--help") | |
usage | |
;; | |
*) | |
echo "Unknown command '$subcommand'" | |
usage | |
;; | |
esac | |
} | |
main $@ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment