| #!/usr/bin/env python3 |
| # Copyright 2017 The ChromiumOS Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Reformat the plugin/ layout into _platform_specific/. |
| |
| The Chrome Webstore (CWS) has a feature where it can create smaller CRX's for |
| users by filtering out arch-specific paths. But it requires the files be placed |
| in specific subdirs. This tool takes care of that for us. |
| |
| https://developer.chrome.com/native-client/devguide/distributing |
| """ |
| |
| import json |
| import os |
| import sys |
| |
| import libdot |
| |
| |
| ARCHES = set(("arm", "x86-32", "x86-64")) |
| |
| |
| def process_manifest(opts, manifest_path, srcroot, dstroot): |
| """Rewrite the manifest to use the _platform_specific feature.""" |
| with open(manifest_path, "rb") as fp: |
| manifest = json.load(fp) |
| if "program" not in manifest: |
| return |
| |
| srcsubpath = os.path.dirname(os.path.relpath(manifest_path, srcroot)) |
| |
| update = False |
| for arch in ARCHES: |
| if arch not in manifest["program"]: |
| continue |
| |
| url = manifest["program"][arch]["url"] |
| if "_platform_specific" in url: |
| if not opts.quiet: |
| print(f"Already relocated: {url}") |
| continue |
| if not url.endswith(".nexe"): |
| if not opts.quiet: |
| print(f"Ignoring non-NaCl file: {url}") |
| continue |
| |
| srcurl = os.path.join(srcroot, srcsubpath, url) |
| dsturl = os.path.join(dstroot, arch, srcsubpath, url) |
| os.makedirs(os.path.dirname(dsturl), exist_ok=True) |
| os.rename(srcurl, dsturl) |
| manifest["program"][arch]["url"] = os.path.relpath( |
| dsturl, os.path.dirname(srcurl) |
| ) |
| update = True |
| |
| if update: |
| if not opts.quiet: |
| print(f"Rewriting manifest for _platform_specific: {manifest_path}") |
| with open(manifest_path, "wb") as fp: |
| json.dump(manifest, fp, sort_keys=True) |
| |
| |
| def get_parser(): |
| """Get a command line parser.""" |
| parser = libdot.ArgumentParser(description=__doc__) |
| parser.add_argument("--base", help="Base path for input/output defaults.") |
| parser.add_argument("--input", help="The plugin directory to read.") |
| parser.add_argument("--output", help="The nacl directory to write.") |
| return parser |
| |
| |
| def main(argv): |
| """The main func!""" |
| parser = get_parser() |
| opts = parser.parse_args(argv) |
| |
| if opts.input is None and opts.output is None: |
| if opts.base is None: |
| parser.error("--base or --input/--output required") |
| opts.input = os.path.join(opts.base, "plugin") |
| opts.output = os.path.join(opts.base, "_platform_specific") |
| |
| for root, _, files in os.walk(opts.input): |
| for f in files: |
| if f.endswith(".nmf"): |
| process_manifest( |
| opts, os.path.join(root, f), opts.input, opts.output |
| ) |
| |
| |
| if __name__ == "__main__": |
| sys.exit(main(sys.argv[1:])) |