diff options
Diffstat (limited to 'rules/bundletool.bzl')
-rw-r--r-- | rules/bundletool.bzl | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/rules/bundletool.bzl b/rules/bundletool.bzl new file mode 100644 index 0000000..161882a --- /dev/null +++ b/rules/bundletool.bzl @@ -0,0 +1,263 @@ +# Copyright 2020 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Bazel Bundletool Commands.""" + +load(":java.bzl", _java = "java") + +_density_mapping = { + "ldpi": 120, + "mdpi": 160, + "hdpi": 240, + "xhdpi": 320, + "xxhdpi": 480, + "xxxhdpi": 640, + "tvdpi": 213, +} + +def _proto_apk_to_module( + ctx, + out = None, + proto_apk = None, + zip = None, + unzip = None): + # TODO(timpeut): rewrite this as a standalone golang tool + ctx.actions.run_shell( + command = """ +set -e + +IN_DIR=$(mktemp -d) +OUT_DIR=$(mktemp -d) +CUR_PWD=$(pwd) +UNZIP=%s +ZIP=%s +INPUT=%s +OUTPUT=%s + +"${UNZIP}" -qq "${INPUT}" -d "${IN_DIR}" +cd "${IN_DIR}" + +if [ -f resources.pb ]; then + mv resources.pb "${OUT_DIR}/" +fi + +if [ -f AndroidManifest.xml ]; then + mkdir "${OUT_DIR}/manifest" + mv AndroidManifest.xml "${OUT_DIR}/manifest/" +fi + +NUM_DEX=`ls -1 *.dex 2>/dev/null | wc -l` +if [ $NUM_DEX != 0 ]; then + mkdir "${OUT_DIR}/dex" + mv *.dex "${OUT_DIR}/dex/" +fi + +if [ -d res ]; then + mv res "${OUT_DIR}/res" +fi + +if [ -d assets ]; then + mv assets "${OUT_DIR}/" +fi + +if [ -d lib ]; then + mv lib "${OUT_DIR}/" +fi + +UNKNOWN=`ls -1 * 2>/dev/null | wc -l` +if [ $UNKNOWN != 0 ]; then + mkdir "${OUT_DIR}/root" + mv * "${OUT_DIR}/root/" +fi + +cd "${OUT_DIR}" +"${CUR_PWD}/${ZIP}" "${CUR_PWD}/${OUTPUT}" -Drq0 . +""" % ( + unzip.executable.path, + zip.executable.path, + proto_apk.path, + out.path, + ), + tools = [zip, unzip], + arguments = [], + inputs = [proto_apk], + outputs = [out], + mnemonic = "Rebundle", + progress_message = "Rebundle to %s" % out.short_path, + ) + +def _build( + ctx, + out = None, + modules = [], + config = None, + metadata = dict(), + bundletool = None, + host_javabase = None): + args = ctx.actions.args() + args.add("build-bundle") + args.add("--output", out) + if modules: + args.add_joined("--modules", modules, join_with = ",") + if config: + args.add("--config", config) + for path, f in metadata.items(): + args.add("--metadata-file", "%s:%s" % (path, f.path)) + + _java.run( + ctx = ctx, + host_javabase = host_javabase, + executable = bundletool, + arguments = [args], + inputs = ( + modules + + ([config] if config else []) + + metadata.values() + ), + outputs = [out], + mnemonic = "BuildBundle", + progress_message = "Building bundle %s" % out.short_path, + ) + +def _extract_config( + ctx, + out = None, + aab = None, + bundletool = None, + host_javabase = None): + # Need to execute as a shell script as the tool outputs to stdout + cmd = """ +set -e +contents=`%s -jar %s dump config --bundle %s` +echo "$contents" > %s +""" % ( + host_javabase[java_common.JavaRuntimeInfo].java_executable_exec_path, + bundletool.executable.path, + aab.path, + out.path, + ) + + ctx.actions.run_shell( + inputs = [aab], + outputs = [out], + tools = depset([bundletool.executable], transitive = [host_javabase[java_common.JavaRuntimeInfo].files]), + mnemonic = "ExtractBundleConfig", + progress_message = "Extract bundle config to %s" % out.short_path, + command = cmd, + ) + +def _extract_manifest( + ctx, + out = None, + aab = None, + module = None, + xpath = None, + bundletool = None, + host_javabase = None): + # Need to execute as a shell script as the tool outputs to stdout + extra_flags = [] + if module: + extra_flags.append("--module " + module) + if xpath: + extra_flags.append("--xpath " + xpath) + cmd = """ +set -e +contents=`%s -jar %s dump manifest --bundle %s %s` +echo "$contents" > %s +""" % ( + host_javabase[java_common.JavaRuntimeInfo].java_executable_exec_path, + bundletool.executable.path, + aab.path, + " ".join(extra_flags), + out.path, + ) + + ctx.actions.run_shell( + inputs = [aab], + outputs = [out], + tools = depset([bundletool.executable], transitive = [host_javabase[java_common.JavaRuntimeInfo].files]), + mnemonic = "ExtractBundleManifest", + progress_message = "Extract bundle manifest to %s" % out.short_path, + command = cmd, + ) + +def _bundle_to_apks( + ctx, + out = None, + bundle = None, + universal = False, + device_spec = None, + keystore = None, + modules = None, + aapt2 = None, + bundletool = None, + host_javabase = None): + inputs = [bundle] + args = ctx.actions.args() + args.add("build-apks") + args.add("--output", out) + args.add("--bundle", bundle) + args.add("--aapt2", aapt2.executable.path) + + if universal: + args.add("--mode=universal") + + if keystore: + args.add("--ks", keystore.path) + args.add("--ks-pass", "pass:android") + args.add("--ks-key-alias", "AndroidDebugKey") + inputs.append(keystore) + + if device_spec: + args.add("--device-spec", device_spec) + inputs.append(device_spec) + + if modules: + args.add_joined("--modules", modules, join_with = ",") + + _java.run( + ctx = ctx, + host_javabase = host_javabase, + executable = bundletool, + arguments = [args], + inputs = inputs, + outputs = [out], + tools = [aapt2], + mnemonic = "BundleToApks", + progress_message = "Converting bundle to .apks: %s" % out.short_path, + ) + +def _build_device_json( + ctx, + out, + abis, + locales, + density, + sdk_version): + json_content = json.encode(struct( + supportedAbis = abis, + supportedLocales = locales, + screenDensity = _density_mapping[density], + sdkVersion = int(sdk_version), + )) + ctx.actions.write(out, json_content) + +bundletool = struct( + build = _build, + build_device_json = _build_device_json, + bundle_to_apks = _bundle_to_apks, + extract_config = _extract_config, + extract_manifest = _extract_manifest, + proto_apk_to_module = _proto_apk_to_module, +) |