Files
react-native-devtools-frontend/scripts/build/build_release_applications.py
T
Simon Zünd 868adc06e7 Don't add sourceURL comments to HTML and Markdown files
Served resources automatically have a 'sourceURL' comment appended
to their content. This CL omits the sourceURL comment for HTML and
Markdown files and keeps Runtime.js in sync with a build script.

R=tvanderlippe@chromium.org

Bug: chromium:1099162
Change-Id: Iee11fd8f620bf736dcd7c4d1bf60e0c1ee49ea4a
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2302594
Commit-Queue: Simon Zünd <szuend@chromium.org>
Reviewed-by: Tim van der Lippe <tvanderlippe@chromium.org>
2020-07-17 12:22:14 +00:00

248 lines
9.6 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#
# Copyright 2016 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.
"""
Builds applications in release mode:
- Concatenates autostart modules, application modules' module.json descriptors,
and the application loader into a single script.
"""
from cStringIO import StringIO
from os import path
from os.path import join
import copy
import os
import re
import shutil
import sys
import subprocess
from modular_build import read_file, write_file, bail_error
import modular_build
import rjsmin
import special_case_namespaces
try:
import simplejson as json
except ImportError:
import json
try:
original_sys_path = sys.path
sys.path = sys.path + [path.join(os.path.dirname(os.path.realpath(__file__)), '..')]
import devtools_paths
finally:
sys.path = original_sys_path
FRONT_END_DIRECTORY = path.join(os.path.dirname(path.abspath(__file__)), '..', '..', 'front_end')
def main(argv):
try:
input_path_flag_index = argv.index('--input_path')
input_path = argv[input_path_flag_index + 1]
output_path_flag_index = argv.index('--output_path')
output_path = argv[output_path_flag_index + 1]
application_names = argv[1:input_path_flag_index]
use_rollup = '--rollup' in argv
except:
print('Usage: %s app_1 app_2 ... app_N --input_path <input_path> --output_path <output_path> --rollup true' % argv[0])
raise
loader = modular_build.DescriptorLoader(input_path)
for app in application_names:
descriptors = loader.load_application(app)
builder = ReleaseBuilder(app, descriptors, input_path, output_path, use_rollup)
builder.build_app()
def copy_file(file_name):
write_file(join(output_path, file_name), minify_js(read_file(join(input_path, file_name))))
copy_file('root.js')
copy_file('RuntimeInstantiator.js')
def resource_source_url(url):
return '\n/*# sourceURL=' + url + ' */'
def minify_js(javascript):
return rjsmin.jsmin(javascript)
def concatenated_module_filename(module_name, output_dir):
return join(output_dir, module_name + '/' + module_name + '_module.js')
# Outputs:
# <app_name>.js
# <module_name>_module.js
class ReleaseBuilder(object):
def __init__(self, application_name, descriptors, application_dir, output_dir, use_rollup):
self.application_name = application_name
self.descriptors = descriptors
self.application_dir = application_dir
self.output_dir = output_dir
self.use_rollup = use_rollup
self._special_case_namespaces = special_case_namespaces.special_case_namespaces
def app_file(self, extension):
return self.application_name + '.' + extension
def autorun_resource_names(self):
result = []
for module in self.descriptors.sorted_modules():
if self.descriptors.application[module].get('type') != 'autostart':
continue
resources = self.descriptors.modules[module].get('resources')
if not resources:
continue
for resource_name in resources:
result.append(path.join(module, resource_name))
return result
def build_app(self):
self._build_app_script()
for module in filter(lambda desc: (not desc.get('type') or desc.get('type') == 'remote'),
self.descriptors.application.values()):
self._concatenate_dynamic_module(module['name'])
def _build_app_script(self):
script_name = self.app_file('js')
output = StringIO()
self._concatenate_application_script(output)
write_file(join(self.output_dir, script_name), minify_js(output.getvalue()))
output.close()
def _release_module_descriptors(self):
module_descriptors = self.descriptors.modules
result = []
for name in module_descriptors:
module = copy.copy(module_descriptors[name])
module_type = self.descriptors.application[name].get('type')
# Clear scripts, as they are not used at runtime
# (only the fact of their presence is important).
resources = module.get('resources', None)
if module.get('scripts') or resources:
if module_type == 'autostart':
if module.get('scripts'):
# Autostart modules are already baked in.
del module['scripts']
else:
# Non-autostart modules are vulcanized.
module['scripts'] = [name + '_module.js']
module['modules'] = module.get('modules', [])
# Resources are already baked into scripts.
if resources is not None:
del module['resources']
result.append(module)
return json.dumps(result)
def _write_module_resources(self, resource_names, output):
for resource_name in resource_names:
resource_name = path.normpath(resource_name).replace('\\', '/')
output.write('self.Runtime.cachedResources["%s"] = "' % resource_name)
resource_content = read_file(path.join(self.application_dir, resource_name))
if not (resource_name.endswith('.html')
or resource_name.endswith('md')):
resource_content += resource_source_url(resource_name).encode(
'utf-8')
resource_content = resource_content.replace('\\', '\\\\')
resource_content = resource_content.replace('\n', '\\n')
resource_content = resource_content.replace('"', '\\"')
output.write(resource_content)
output.write('";\n')
def _concatenate_autostart_modules(self, output):
non_autostart = set()
sorted_module_names = self.descriptors.sorted_modules()
for name in sorted_module_names:
desc = self.descriptors.modules[name]
name = desc['name']
type = self.descriptors.application[name].get('type')
if type == 'autostart':
deps = set(desc.get('dependencies', []))
non_autostart_deps = deps & non_autostart
if len(non_autostart_deps):
bail_error(
'Non-autostart dependencies specified for the autostarted module "%s": %s' % (name, non_autostart_deps))
self._rollup_module(name, desc.get('modules', []),
desc.get('skip_rollup', False))
else:
non_autostart.add(name)
def _concatenate_application_script(self, output):
output.write('Root.allDescriptors.push(...%s);' % self._release_module_descriptors())
if self.descriptors.extends:
output.write('Root.applicationDescriptor.modules.push(...%s);' % json.dumps(self.descriptors.application.values()))
else:
output.write('Root.applicationDescriptor = %s;' % self.descriptors.application_json())
output.write(minify_js(read_file(join(self.application_dir, self.app_file('js')))))
self._concatenate_autostart_modules(output)
self._write_module_resources(self.autorun_resource_names(), output)
def _concatenate_dynamic_module(self, module_name):
module = self.descriptors.modules[module_name]
scripts = module.get('scripts')
modules = module.get('modules')
resources = self.descriptors.module_resources(module_name)
module_dir = join(self.application_dir, module_name)
output = StringIO()
if scripts:
modular_build.concatenate_scripts(scripts, module_dir, self.output_dir, output)
if resources:
self._write_module_resources(resources, output)
if modules:
self._rollup_module(module_name, modules,
module.get('skip_rollup', False))
output_file_path = concatenated_module_filename(module_name, self.output_dir)
write_file(output_file_path, minify_js(output.getvalue()))
output.close()
def _rollup_module(self, module_name, modules, skip_rollup):
legacyFileName = module_name + '-legacy.js'
if legacyFileName in modules:
write_file(
join(self.output_dir, module_name, legacyFileName),
minify_js(
read_file(
join(self.application_dir, module_name,
legacyFileName))))
# Temporary hack, as we use `devtools_entrypoint` for this module now
# TODO(crbug.com/1101738): remove once all folders are migrated
if skip_rollup:
return
js_entrypoint = join(self.application_dir, module_name, module_name + '.js')
out = ''
if self.use_rollup:
rollup_process = subprocess.Popen([
devtools_paths.node_path(),
devtools_paths.rollup_path(), '--config',
join(FRONT_END_DIRECTORY, 'rollup.config.js'), '--input',
js_entrypoint
],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
out, error = rollup_process.communicate()
if rollup_process.returncode != 0:
print(error)
sys.exit(rollup_process.returncode)
else:
out = read_file(js_entrypoint)
write_file(join(self.output_dir, module_name, module_name + '.js'),
minify_js(out))
if __name__ == '__main__':
sys.exit(main(sys.argv))