Commit dd300217 authored by Mohamed Heikal's avatar Mohamed Heikal Committed by Commit Bot

Add local deployment option to upload_html_viewer.py

Currently it is not easy to test the supersize viewer without uploading
a dev version to the production site. Add option to
upload_html_viewer.py to host locally. Also adds a staging option
because WFH and local development don't mix so well.

Change-Id: Ieb79a47ba836898cf9da28805ce3c6a9a3e208a3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2485781
Commit-Queue: Mohamed Heikal <mheikal@chromium.org>
Reviewed-by: default avatarAndrew Grieve <agrieve@chromium.org>
Cr-Commit-Position: refs/heads/master@{#820273}
parent 5e72cdeb
...@@ -22,12 +22,12 @@ gn gen out/caspian --args='is_official_build=true treat_warnings_as_errors=false ...@@ -22,12 +22,12 @@ gn gen out/caspian --args='is_official_build=true treat_warnings_as_errors=false
Then run locally via: Then run locally via:
```sh ```sh
tools/binary_size/supersize start_server out.size tools/binary_size/libsupersize/upload_html_viewer.py --local
``` ```
or upload to hosted site via: or upload to hosted site via:
```sh ```sh
tools/binary_size/libsupersize/upload_html_viewer.py tools/binary_size/libsupersize/upload_html_viewer.py [--prod | --staging]
``` ```
To re-create .patch file: To re-create .patch file:
......
...@@ -287,7 +287,7 @@ def Run(args, on_config_error): ...@@ -287,7 +287,7 @@ def Run(args, on_config_error):
logging.warning('Done!') logging.warning('Done!')
msg = [ msg = [
'View using a local server via: ', 'View using a local server via: ',
' {0} start_server {1}', ' {0}/upload_html_viwer.py --local',
'or run:', 'or run:',
' gsutil.py cp -a public-read {1} gs://chrome-supersize/oneoffs/' ' gsutil.py cp -a public-read {1} gs://chrome-supersize/oneoffs/'
'{2}.ndjson', '{2}.ndjson',
...@@ -296,8 +296,7 @@ def Run(args, on_config_error): ...@@ -296,8 +296,7 @@ def Run(args, on_config_error):
'?load_url=oneoffs/{2}.ndjson', '?load_url=oneoffs/{2}.ndjson',
] ]
supersize_path = os.path.relpath( supersize_path = os.path.relpath(
os.path.join(path_util.TOOLS_SRC_ROOT, 'tools', 'binary_size', os.path.join(path_util.TOOLS_SRC_ROOT, 'tools', 'binary_size'))
'supersize'))
# Use a random UUID as the filename so user can copy-and-paste command # Use a random UUID as the filename so user can copy-and-paste command
# directly without a name collision. # directly without a name collision.
upload_id = uuid.uuid4() upload_id = uuid.uuid4()
......
...@@ -19,7 +19,6 @@ import console ...@@ -19,7 +19,6 @@ import console
import diff import diff
import file_format import file_format
import html_report import html_report
import start_server
def _LogPeakRamUsage(): def _LogPeakRamUsage():
...@@ -96,8 +95,6 @@ def main(): ...@@ -96,8 +95,6 @@ def main():
actions['archive'] = (archive, 'Create a .size file') actions['archive'] = (archive, 'Create a .size file')
actions['html_report'] = ( actions['html_report'] = (
html_report, 'Create a stand-alone report from a .size file.') html_report, 'Create a stand-alone report from a .size file.')
actions['start_server'] = (
start_server, 'Start a web server to view data generated by html_report')
actions['console'] = ( actions['console'] = (
console, console,
'Starts an interactive Python console for analyzing .size files.') 'Starts an interactive Python console for analyzing .size files.')
......
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Runs a server to let the user interact with supersize using a web UI."""
import http.server
import logging
import os
class SupersizeHTTPRequestHandler(http.server.SimpleHTTPRequestHandler, object):
# Directory to serve files from
serve_from = None
# Path to data file
data_file_path = None
before_file_path = None
#override
def translate_path(self, path):
f = super(SupersizeHTTPRequestHandler, self).translate_path(path)
relative_path = os.path.relpath(f, os.getcwd())
if relative_path in ['data.ndjson', 'data.size']:
return SupersizeHTTPRequestHandler.data_file_path
if relative_path == 'before.size':
return SupersizeHTTPRequestHandler.before_file_path
else:
return os.path.join(SupersizeHTTPRequestHandler.serve_from, relative_path)
def AddArguments(parser):
parser.add_argument('report_file',
help='Path to a custom html_report data file to load.')
parser.add_argument(
'-b',
'--before_file',
type=str,
default='',
help=('Path to a "before" .size file to diff against. If present, '
'report_file should also be a .size file.'))
parser.add_argument('-p', '--port', type=int, default=8000,
help='Port for the HTTP server')
parser.add_argument('-a', '--address', default='localhost',
help='Address for the HTTP server')
# pylint: disable=unused-argument
def Run(args, on_config_error):
logging.info('Starting server')
server_addr = (args.address, args.port)
static_files = os.path.join(os.path.dirname(__file__), 'static')
SupersizeHTTPRequestHandler.serve_from = static_files
SupersizeHTTPRequestHandler.data_file_path = args.report_file
SupersizeHTTPRequestHandler.before_file_path = args.before_file
SupersizeHTTPRequestHandler.extensions_map['.wasm'] = 'application/wasm'
httpd = http.server.HTTPServer(server_addr, SupersizeHTTPRequestHandler)
sa = httpd.socket.getsockname()
is_ndjson = args.report_file.endswith('ndjson')
data_file = 'data.ndjson' if is_ndjson else 'data.size'
maybe_before_file = '&before_url=before.size' if args.before_file else ''
logging.warning(
'Server ready at http://%s:%d/viewer.html?load_url=' + data_file +
maybe_before_file, sa[0], sa[1])
httpd.serve_forever()
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
"""Update the firebase project hosting the Super Size UI.""" """Update the firebase project hosting the Super Size UI."""
import argparse
import os import os
import shutil import shutil
import subprocess import subprocess
...@@ -15,6 +16,10 @@ import uuid ...@@ -15,6 +16,10 @@ import uuid
FIREBASE_PROJECT = 'chrome-supersize' FIREBASE_PROJECT = 'chrome-supersize'
PROD = 'prod'
STAGING = 'staging'
DEV = 'dev'
def _FirebaseLogin(): def _FirebaseLogin():
"""Login into the Firebase CLI""" """Login into the Firebase CLI"""
...@@ -48,10 +53,23 @@ def _FirebaseInitProjectDir(project_dir): ...@@ -48,10 +53,23 @@ def _FirebaseInitProjectDir(project_dir):
return static_dir return static_dir
def _FirebaseDeploy(project_dir): def _FirebaseDeploy(project_dir, deploy_mode=PROD):
"""Deploy the project to firebase hosting.""" """Deploy the project to firebase hosting."""
subprocess.check_call(['firebase', 'deploy', '-P', FIREBASE_PROJECT], if deploy_mode == DEV:
cwd=project_dir) subprocess.check_call([
'firebase', '-P', FIREBASE_PROJECT, 'emulators:start', '--only',
'hosting'
],
cwd=project_dir)
elif deploy_mode == STAGING:
print('Note: deploying to staging requires firebase cli >= 8.12.0')
subprocess.check_call([
'firebase', '-P', FIREBASE_PROJECT, 'hosting:channel:deploy', 'staging'
],
cwd=project_dir)
else:
subprocess.check_call(['firebase', 'deploy', '-P', FIREBASE_PROJECT],
cwd=project_dir)
def _CopyStaticFiles(project_static_dir): def _CopyStaticFiles(project_static_dir):
...@@ -79,20 +97,41 @@ def _Prompt(message): ...@@ -79,20 +97,41 @@ def _Prompt(message):
def main(): def main():
parser = argparse.ArgumentParser()
deployment_mode_group = parser.add_mutually_exclusive_group(required=True)
deployment_mode_group.add_argument('--local',
action='store_const',
dest='deploy_mode',
const=DEV,
help='Deploy a locally hosted server.')
deployment_mode_group.add_argument(
'--staging',
action='store_const',
dest='deploy_mode',
const=STAGING,
help='Deploy to staging channel (does not support authenticated '
'requests).')
deployment_mode_group.add_argument('--prod',
action='store_const',
dest='deploy_mode',
const=PROD,
help='Deploy to prod.')
options = parser.parse_args()
message = ( message = (
"""This script deploys the contents of //tools/binary_size/libsupersize/static """This script deploys the contents of //tools/binary_size/libsupersize/static
to firebase hosting at chrome-supersize.firebaseapp.com. Please ensure you have to firebase hosting at chrome-supersize.firebaseapp.com. Please ensure you have
read the instructions at //tools/binary_size/libsupersize/static/README.md first read the instructions at //tools/binary_size/libsupersize/static/README.md first
before running this. Are you sure you want to continue?""") before running this. Are you sure you want to continue?""")
if _Prompt(message): if options.deploy_mode != PROD or _Prompt(message):
_CheckFirebaseCLI() _CheckFirebaseCLI()
_FirebaseLogin() _FirebaseLogin()
with tempfile.TemporaryDirectory(prefix='firebase-') as project_dir: with tempfile.TemporaryDirectory(prefix='firebase-') as project_dir:
static_dir = _FirebaseInitProjectDir(project_dir) static_dir = _FirebaseInitProjectDir(project_dir)
_CopyStaticFiles(static_dir) _CopyStaticFiles(static_dir)
_FillInAndCopyTemplates(static_dir) _FillInAndCopyTemplates(static_dir)
_FirebaseDeploy(project_dir) _FirebaseDeploy(project_dir, deploy_mode=options.deploy_mode)
else: else:
print('Nothing was deployed.') print('Nothing was deployed.')
......
...@@ -61,6 +61,5 @@ libsupersize/nm.py ...@@ -61,6 +61,5 @@ libsupersize/nm.py
libsupersize/obj_analyzer.py libsupersize/obj_analyzer.py
libsupersize/parallel.py libsupersize/parallel.py
libsupersize/path_util.py libsupersize/path_util.py
libsupersize/start_server.py
libsupersize/string_extract.py libsupersize/string_extract.py
libsupersize/zip_util.py libsupersize/zip_util.py
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment