Skip to content

Commit

Permalink
webview build: add new script tools/build-webview
Browse files Browse the repository at this point in the history
At present, when loading content into the WebView, we inject all
non-image assets as part of the generated HTML. This is more than a
bit wasteful, considering that large swaths of the supporting CSS and
JavaScript is entirely static from invocation to invocation;
additionally, it makes KaTeX support somewhere between "nontrivial"
and "impossible".

This commit creates a build subsystem which can inject static
webview-supporting assets into the application bundle, into a
`webview` directory.

We also create a stub directory for the subsystem to copy assets from;
at present this contains only a README.md file (which will *not* be
copied), but this will be expanded in the following series of commits.

Inspired by #2690. Assists with #2660, #3595, and potentially many
other issues.
  • Loading branch information
rk-for-zulip authored and gnprice committed Oct 11, 2019
1 parent bfb15d7 commit e6b1936
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/webview/static/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Webview static files

This directory holds static files to be packaged for use by the embedded
WebView. Files herein (other than those named `README.md`) will be copied out to
the packaged application at build time.

Although the files in this directory are static at _runtime_, some of them may
still be generated dynamically at _build time_. Such files should not be tracked
in the Git repository, but instead rebuilt as needed; see [the build-webview
script][build-webview] for an appropriate hook.

[build-webview]: ../../../tools/build-webview

_N.B._: When editing and testing, changes made to this directory will **not** be
uploaded to an emulator after a mere reload! You must perform a rebuild
(`react-native run-${TARGET}`) to repackage any new or altered assets.
144 changes: 144 additions & 0 deletions tools/build-webview
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
#!/bin/bash
set -eu
unset CDPATH

# CAVEAT EMENDATOR: Neither of the build systems have any visibility into this
# script's dependencies -- it is run unconditionally, and must ensure on its own
# that it performs as few actions as possible when nothing has changed.

################################################################################
# Common functions
################################################################################

# print usage message; do not die
usage() {
cat >&2 <<EOF
usage: $0 [ios | android] --destination DEST
Builds a platform-local intermediate directory containing files used by the
message-list WebView. The target platform (either \`ios\` or \`android\`) must
be specified, along with the expected destination directory.
(This script is usually run automatically by the build system.)
EOF
}

# print error and die
err() {
echo "$0:" $'\e[31merror:\e[0m' "$1" >&2
exit 1;
}



################################################################################
# Parameters and environment
################################################################################

# chdir to the current git repo's root
ROOT="$(git rev-parse --show-toplevel)"
cd "$ROOT"

# Parse arguments. Sloppy, but sufficient for now.
unset TARGET
unset DEST
while (( $# )); do
case "$1" in
--help|-h|help)
usage; exit 0;;
android|ios)
# no check for multiple nouns; oh well
TARGET="$1"; shift;;
--destination)
# note: this doesn't permit an equals sign after `--destination`
shift; DEST="$1"; shift;;
*) usage; exit 2;;
esac
done

if [ -z "${TARGET-}" ]; then
usage; exit 2
elif [ -z "${DEST-}" ]; then
usage; exit 2
fi

# Sanity-check DEST and TARGET.
case "$TARGET" in
ios)
if [ "$(uname)" != "Darwin" ]; then
err "iOS builds only supported on macOS";
fi

# $DEST should be copied to `${bundle_root}/webview`.
#
# $DEST itself must be specified twice in Xcode: once in the invocation
# of this script, and once in the "Copy Bundle Resources" step. If you
# change it, you'll need to change it in both places. (And here, of
# course.)
if [[ "$DEST" != "$ROOT/ios/"* ]]; then
err "unexpected destination directory '$DEST' (expected target in iOS build dir)"
fi
;;
android)
# $DEST should be copied to `file:///android_asset/webview`.
#
# Gradle -- more precisely, the Android Gradle plugin -- is already
# configured to copy some directory from `build/` into the APK. We
# determine which directory that is in Gradle, and pass it here.
if [[ "$DEST" != "$ROOT/android/app/build/"* ]]; then
err "unexpected destination directory '$DEST' (expected target in Android build dir)"
fi
;;
*) err "impossible target $TARGET";;
esac

# As implied above, the ultimate destination of these files should be a
# directory named `./webview` (relative to the platform-dependent asset
# root directory).
#
# The target directory basename should therefore be 'webview': both build
# systems will preserve the name they're given here.
if [[ "$DEST" != *"/webview" ]]; then
err "unexpected destination directory '$DEST'"
fi

# Set SRC.
SRC=src/webview/static
if [ ! -d "$SRC" ]; then
err "cannot find asset source directory '$SRC'";
fi


################################################################################
# Pre-sync: platform-agnostic build steps
################################################################################

# Currently none, but this is where they'll go.
#
# TODO: Use something like `make -f src/webview/static.Makefile`, to ensure that
# complicated build steps are not run unconditionally.
#
# TODO: split assets into build-time-generated and build-time-static?
# - rsync can sync from multiple directories, but has no collision-detection
# - might be too many layers of abstraction



################################################################################
# Sync
################################################################################

# Sync the directory structure, preserving metadata. (We ignore any files named
# 'README.md'; these should be strictly informative.)
#
# We use `rsync` here, as it will skip unchanged files.
mkdir -p "$DEST"
rsync -a --no-D --delete --delete-excluded --exclude=README.md "$SRC/." "$DEST"



################################################################################
# Post-sync: platform-specific build steps
################################################################################

# None yet.

0 comments on commit e6b1936

Please sign in to comment.