Replace update_bazel_workspace.sh with a python script (#1271)

This script is (IMO) more readable, but the real reason for this change is that
it raises an error message when the binary package fails to download. (The shell
script silently generated a bogus hash instead, because the shell's `set -e`
builtin does not affect commands executing inside a $() context.
It seemed just as easy to rewrite the script in Python as to fix that.

This change also updates some outdated filename references.
diff --git a/bazel/revisions.bzl b/bazel/revisions.bzl
index 6145db8..f944578 100644
--- a/bazel/revisions.bzl
+++ b/bazel/revisions.bzl
@@ -1,4 +1,4 @@
-# This file is automatically updated by emsdk/scripts/update_bazel_workspace.sh
+# This file is automatically updated by emsdk/scripts/update_bazel_workspace.py
 # DO NOT MODIFY
 
 EMSCRIPTEN_TAGS = {
diff --git a/scripts/create_release.py b/scripts/create_release.py
index 418dcab..2d6d312 100755
--- a/scripts/create_release.py
+++ b/scripts/create_release.py
@@ -53,7 +53,9 @@
     f.write(json.dumps(release_info, indent=2))
     f.write('\n')
 
-  subprocess.check_call([os.path.join(script_dir, 'update_bazel_workspace.sh')], cwd=root_dir)
+  subprocess.check_call(
+    [sys.executable, os.path.join(script_dir, 'update_bazel_workspace.py')],
+    cwd=root_dir)
 
   branch_name = 'version_' + new_version
 
diff --git a/scripts/update_bazel_workspace.py b/scripts/update_bazel_workspace.py
new file mode 100755
index 0000000..932cc72
--- /dev/null
+++ b/scripts/update_bazel_workspace.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python3
+# This script will update emsdk/bazel/revisons.bzl to the latest version of
+# emscripten. It reads emsdk/emscripten-releases-tags.json to get the latest
+# version number. Then, it downloads the prebuilts for that version and computes
+# the sha256sum for the archive. It then puts all this information into the
+# emsdk/bazel/revisions.bzl file.
+
+import hashlib
+import json
+import os
+import requests
+import sys
+
+STORAGE_URL = 'https://storage.googleapis.com/webassembly/emscripten-releases-builds'
+
+EMSDK_ROOT = os.path.dirname(os.path.dirname(__file__))
+RELEASES_TAGS_FILE = EMSDK_ROOT + '/emscripten-releases-tags.json'
+BAZEL_REVISIONS_FILE = EMSDK_ROOT + '/bazel/revisions.bzl'
+
+
+def get_latest_info():
+    with open(RELEASES_TAGS_FILE) as f:
+        info = json.load(f)
+    latest = info['aliases']['latest']
+    return latest, info['releases'][latest]
+
+
+def get_sha(platform, archive_fmt, latest_hash, arch_suffix=''):
+    r = requests.get(f'{STORAGE_URL}/{platform}/{latest_hash}/wasm-binaries{arch_suffix}.{archive_fmt}')
+    r.raise_for_status()
+    print(f'Fetching {r.url}')
+    h = hashlib.new('sha256')
+    for chunk in r.iter_content(chunk_size=1024):
+        h.update(chunk)
+    return h.hexdigest()
+
+
+def revisions_item(version, latest_hash):
+    return f'''\
+    "{version}": struct(
+        hash = "{latest_hash}",
+        sha_linux = "{get_sha('linux', 'tbz2', latest_hash)}",
+        sha_mac = "{get_sha('mac', 'tbz2', latest_hash)}",
+        sha_mac_arm64 = "{get_sha('mac', 'tbz2', latest_hash, '-arm64')}",
+        sha_win = "{get_sha('win', 'zip', latest_hash)}",
+    ),
+'''
+
+
+def insert_revision(item):
+    with open(BAZEL_REVISIONS_FILE, 'r') as f:
+        lines = f.readlines()
+
+    lines.insert(lines.index('EMSCRIPTEN_TAGS = {\n') + 1, item)
+
+    with open(BAZEL_REVISIONS_FILE, 'w') as f:
+        f.write(''.join(lines))
+
+
+def main(argv):
+    version, latest_hash = get_latest_info()
+    item = revisions_item(version, latest_hash)
+    print('inserting item:')
+    print(item)
+    insert_revision(item)
+
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))
diff --git a/scripts/update_bazel_workspace.sh b/scripts/update_bazel_workspace.sh
deleted file mode 100755
index b2f7078..0000000
--- a/scripts/update_bazel_workspace.sh
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/bin/bash
-# This script will update emsdk/bazel/WORKSPACE to the latest version of
-# emscripten. It reads emsdk/emscripten-releases-tags.json to get the latest
-# version number. Then, it downloads the prebuilts for that version and computes
-# the sha256sum for the archive. It then puts all this information into the
-# emsdk/bazel/WORKSPACE file.
-
-ERR=0
-# Attempt to change to the emsdk root directory
-cd $(dirname $0)/..
-
-# If the previous command succeeded. We are in the emsdk root. Check to make
-# sure the files and directories we need are present.
-if [[ $? = 0 ]]; then
-  if [[ ! -f emscripten-releases-tags.json ]]; then
-    echo "Cannot find emscripten-releases-tags.json."
-    ERR=1
-  fi
-
-  if [[ ! -d bazel ]]; then
-    echo "Cannot find the bazel directory."
-    ERR=1
-  elif [[ ! -f bazel/WORKSPACE ]]; then
-    echo "Cannot find bazel/WORKSPACE."
-    ERR=1
-  fi
-else
-  ERR=1
-fi
-
-if [[ $ERR = 1 ]]; then
-  echo "Unable to cd into the emsdk root directory."
-  exit 1
-fi
-
-URL1=https://storage.googleapis.com/webassembly/emscripten-releases-builds/
-URL2=/wasm-binaries
-
-# Get commit hash for $1 version
-get_hash () {
-  echo $(grep "$1" emscripten-releases-tags.json | grep -v latest | grep -v asserts | cut -f4 -d\")
-}
-
-# Get sha256 for $1 os $2 extname $3 hash $4 architecture
-get_sha () {
-  echo $(curl "${URL1}$1/$3${URL2}$4.$2" 2>/dev/null | sha256sum | awk '{print $1}')
-}
-
-# Assemble dictionary line
-revisions_item () {
-  hash=$(get_hash $1)
-  echo \
-      "\    \"$1\": struct(\n" \
-      "\       hash = \"$(get_hash ${hash})\",\n" \
-      "\       sha_linux = \"$(get_sha linux tbz2 ${hash})\",\n" \
-      "\       sha_mac = \"$(get_sha mac tbz2 ${hash})\",\n" \
-      "\       sha_mac_arm64 = \"$(get_sha mac tbz2 ${hash} -arm64)\",\n" \
-      "\       sha_win = \"$(get_sha win zip ${hash})\",\n" \
-      "\   ),"
-}
-
-append_revision () {
-  sed -i "5 i $(revisions_item $1)" bazel/revisions.bzl
-}
-
-# Get the latest version number from emscripten-releases-tag.json.
-VER=$(grep -oP '(?<=latest\": \")([\d\.]+)(?=\")' \
-        emscripten-releases-tags.json \
-      | sed --expression "s/\./\\\./g")
-
-append_revision ${VER}
-
-echo "Done!"
diff --git a/test/test_bazel.sh b/test/test_bazel.sh
index f52daa4..bc53fcd 100755
--- a/test/test_bazel.sh
+++ b/test/test_bazel.sh
@@ -14,7 +14,7 @@
       | grep -v latest \
       | cut -f4 -d\")
 
-FAILMSG="!!! scripts/update_bazel_toolchain.sh needs to be run !!!"
+FAILMSG="!!! scripts/update_bazel_workspace.py needs to be run !!!"
 
 # Ensure the WORKSPACE file is up to date with the latest version.
 grep ${VER} bazel/revisions.bzl || (echo ${FAILMSG} && false)
diff --git a/test/test_bazel_mac.sh b/test/test_bazel_mac.sh
index 0a26a0c..58aa9f0 100755
--- a/test/test_bazel_mac.sh
+++ b/test/test_bazel_mac.sh
@@ -14,7 +14,7 @@
       | grep -v latest \
       | cut -f4 -d\")
 
-FAILMSG="!!! scripts/update_bazel_toolchain.sh needs to be run !!!"
+FAILMSG="!!! scripts/update_bazel_workspace.py needs to be run !!!"
 
 # Ensure the WORKSPACE file is up to date with the latest version.
 grep ${VER} bazel/revisions.bzl || (echo ${FAILMSG} && false)