Chromium Code Reviews| Index: chrome/browser/resources/vulcanize_gn.py |
| diff --git a/chrome/browser/resources/vulcanize_gn.py b/chrome/browser/resources/vulcanize_gn.py |
| index e6983018f02b42ae9df154a1b09c9aa504f76e8c..7485bf1729b046e593fadd76d4231e66a1b8f93d 100755 |
| --- a/chrome/browser/resources/vulcanize_gn.py |
| +++ b/chrome/browser/resources/vulcanize_gn.py |
| @@ -10,6 +10,8 @@ import platform |
| import re |
| import sys |
| import tempfile |
| +import json |
|
michaelpg
2017/07/19 18:51:59
nit: alphabetical
dpapad
2017/07/19 20:49:38
Done.
|
| +import shutil |
| _HERE_PATH = os.path.dirname(__file__) |
| @@ -43,16 +45,19 @@ _POLYMER_PATH = os.path.join( |
| _VULCANIZE_BASE_ARGS = [ |
| # These files are already combined and minified. |
| '--exclude', 'chrome://resources/html/polymer.html', |
| - '--exclude', 'web-animations-next-lite.min.js', |
| + '--exclude', 'chrome://resources/polymer/v1_0/polymer/polymer.html', |
| + '--exclude', 'chrome://resources/polymer/v1_0/polymer/polymer-micro.html', |
| + '--exclude', 'chrome://resources/polymer/v1_0/polymer/polymer-mini.html', |
| + '--exclude', 'chrome://resources/polymer/v1_0/web-animations-js/web-animations-next-lite.min.js', |
| - # These files are dynamically created by C++. |
| - '--exclude', 'load_time_data.js', |
| - '--exclude', 'strings.js', |
| - '--exclude', 'text_defaults.css', |
| - '--exclude', 'text_defaults_md.css', |
| + '--exclude', 'chrome://resources/css/roboto.css', |
| + '--exclude', 'chrome://resources/css/text_defaults.css', |
| + '--exclude', 'chrome://resources/css/text_defaults_md.css', |
| + '--exclude', 'chrome://resources/js/load_time_data.js', |
| '--inline-css', |
| '--inline-scripts', |
| + '--rewrite-urls-in-templates', |
| '--strip-comments', |
| ] |
| @@ -77,32 +82,24 @@ def _undo_mapping(mappings, url): |
| # TODO(dbeam): can we make this stricter? |
| return url |
| -def _request_list_path(out_path, html_out_file): |
| - return os.path.join(out_path, html_out_file + '_requestlist.txt') |
| +def _request_list_path(out_path, host): |
| + return os.path.join(out_path, host + '_requestlist.txt') |
| -# Get a list of all files that were bundled with Vulcanize and update the |
| -# depfile accordingly such that Ninja knows when to trigger re-vulcanization. |
| -def _update_dep_file(in_folder, args): |
| +# Get a list of all files that were bundled with polymer-bundler and update the |
| +# depfile accordingly such that Ninja knows when to re-trigger. |
| +def _update_dep_file(in_folder, args, manifest): |
| in_path = os.path.join(_CWD, in_folder) |
| - out_path = os.path.join(_CWD, args.out_folder) |
| - # Prior call to vulcanize already generated the deps list, grab it from there. |
| - request_list_path = _request_list_path(out_path, args.html_out_file) |
| - request_list = open(request_list_path, 'r').read().splitlines() |
| - |
| - if platform.system() == 'Windows': |
| - # TODO(dbeam): UGH. For some reason Vulcanize is interpreting the target |
| - # file path as a URL and using the drive letter (e.g. D:\) as a protocol. |
| - # This is a little insane, but we're fixing here by normalizing case (which |
| - # really shouldn't matter, these are all file paths and generally are all |
| - # lower case) and writing from / to \ (file path) and then back again. This |
| - # is compounded by NodeJS having a bug in url.resolve() that handles |
| - # chrome:// protocol URLs poorly as well as us using startswith() to strip |
| - # file paths (which isn't crazy awesome either). Don't remove unless you |
| - # really really know what you're doing. |
| - norm = lambda u: u.lower().replace('/', '\\') |
| - request_list = [norm(u).replace(norm(in_path), '').replace('\\', '/') |
| - for u in request_list] |
| + # Gather the dependencies of all bundled root HTML files. |
| + request_list = [] |
| + for html_file in manifest: |
| + request_list += manifest[html_file] |
| + |
| + # Add a slash in front of every dependency that is not a chrome:// URL, so |
| + # that we can map it to the correct source file path below. |
| + request_list = map( |
| + lambda dep: '/' + dep if not dep.startswith('chrome://') else dep, |
| + request_list) |
| # Undo the URL mappings applied by vulcanize to get file paths relative to |
| # current working directory. |
| @@ -121,81 +118,86 @@ def _update_dep_file(in_folder, args): |
| deps = [d for d in deps if not d.startswith(filter_url)] |
| with open(os.path.join(_CWD, args.depfile), 'w') as f: |
| - deps_file_header = os.path.join(args.out_folder, args.html_out_file) |
| + deps_file_header = os.path.join(args.out_folder, args.html_out_files[0]) |
| f.write(deps_file_header + ': ' + ' '.join(deps)) |
| def _vulcanize(in_folder, args): |
| in_path = os.path.normpath(os.path.join(_CWD, in_folder)) |
| out_path = os.path.join(_CWD, args.out_folder) |
| - |
| - html_out_path = os.path.join(out_path, args.html_out_file) |
| - js_out_path = os.path.join(out_path, args.js_out_file) |
| + manifest_out_path = _request_list_path(out_path, args.host) |
| exclude_args = [] |
| for f in args.exclude or []: |
| exclude_args.append('--exclude') |
| exclude_args.append(f) |
| - output = node.RunNode( |
| - [node_modules.PathToVulcanize()] + |
| - _VULCANIZE_BASE_ARGS + _VULCANIZE_REDIRECT_ARGS + exclude_args + |
| - ['--out-request-list', _request_list_path(out_path, args.html_out_file), |
| - '--redirect', '"/|%s"' % in_path, |
| - '--redirect', '"chrome://%s/|%s"' % (args.host, in_path), |
| - # TODO(dpapad): Figure out why vulcanize treats the input path |
| - # differently on Windows VS Linux/Mac. |
| - os.path.join( |
| - in_path if platform.system() == 'Windows' else os.sep, |
| - args.html_in_file)]) |
| - |
| - # Grit includes are not supported, use HTML imports instead. |
| - output = output.replace('<include src="', '<include src-disabled="') |
| + in_html_args = [] |
| + for f in args.html_in_files: |
| + in_html_args.append('--in-html') |
| + in_html_args.append(f) |
| - if args.insert_in_head: |
| - assert '<head>' in output |
| - # NOTE(dbeam): Vulcanize eats <base> tags after processing. This undoes |
| - # that by adding a <base> tag to the (post-processed) generated output. |
| - output = output.replace('<head>', '<head>' + args.insert_in_head) |
| - |
| - crisper_input = tempfile.NamedTemporaryFile(mode='wt+', delete=False) |
| - crisper_input.write(output) |
| - crisper_input.close() |
| + tmp_out_dir = os.path.join(out_path, 'bundled') |
| + node.RunNode( |
| + [node_modules.PathToBundler()] + |
| + _VULCANIZE_BASE_ARGS + _VULCANIZE_REDIRECT_ARGS + exclude_args + |
| + [# This file is dynamically created by C++. Need to specify an exlusion |
|
calamity
2017/07/19 06:15:33
nit: exclusion
dpapad
2017/07/19 20:49:38
Done.
|
| + # URL for both the relative URL and chrome:// URL syntax. |
| + '--exclude', 'strings.js', |
| + '--exclude', 'chrome://%s/strings.js' % args.host, |
| - crisper_output = tempfile.NamedTemporaryFile(mode='wt+', delete=False) |
| - crisper_output.close() |
| + '--manifest-out', manifest_out_path, |
| + '--root', in_path, |
| + '--redirect', '"chrome://%s/|%s"' % (args.host, in_path), |
| + '--out-dir', os.path.relpath(tmp_out_dir, _CWD), |
| + '--shell', args.html_in_files[0], |
| + ] + in_html_args) |
| + |
| + for index, html_file in enumerate(args.html_in_files): |
| + with open( |
| + os.path.join(os.path.relpath(tmp_out_dir, _CWD), html_file), 'r') as f: |
| + output = f.read() |
| + |
| + # Grit includes are not supported, use HTML imports instead. |
| + output = output.replace('<include src="', '<include src-disabled="') |
| + |
| + if args.insert_in_head: |
| + assert '<head>' in output |
| + # NOTE(dbeam): polymer-bundler eats <base> tags after processing. This |
| + # undoes that by adding a <base> tag to the (post-processed) generated |
| + # output. |
| + output = output.replace('<head>', '<head>' + args.insert_in_head) |
| + |
| + # Open file again with 'w' such that the previous contents are overwritten. |
| + with open( |
| + os.path.join(os.path.relpath(tmp_out_dir, _CWD), html_file), 'w') as f: |
| + f.write(output) |
| + f.close() |
| try: |
| - node.RunNode([node_modules.PathToCrisper(), |
| - '--source', crisper_input.name, |
| - '--script-in-head', 'false', |
| - '--only-split', |
| - '--html', html_out_path, |
| - '--js', crisper_output.name]) |
| - |
| - # Crisper by default inserts a <script> tag with the name of the --js file, |
| - # but since we are using a temporary file, need to manually insert a |
| - # <script> tag with the correct final filename (in combination with |
| - # --only-split flag). There is no way currently to manually specify the |
| - # <script> tag's path, see https://github.com/PolymerLabs/crisper/issues/46. |
| - with open(html_out_path, 'r+') as f: |
| - data = f.read() |
| - new_data = data.replace( |
| - '</body></html>', |
| - '<script src="' + args.js_out_file + '"></script></body></html>') |
| - assert new_data != data, 'Expected to find </body></html> token.' |
| - f.seek(0) |
| - f.write(new_data) |
| - f.truncate() |
| - |
| - node.RunNode([node_modules.PathToUglify(), crisper_output.name, |
| - '--comments', '"/Copyright|license|LICENSE|\<\/?if/"', |
| - '--output', js_out_path]) |
| + for index, html_in_file in enumerate(args.html_in_files): |
| + html_out_file = args.html_out_files[index] |
| + js_out_file = args.js_out_files[index] |
| + |
| + # Run crisper to separate the JS from the HTML file. |
| + node.RunNode([node_modules.PathToCrisper(), |
| + '--source', os.path.join(tmp_out_dir, html_in_file), |
| + '--script-in-head', 'false', |
| + '--html', os.path.join(tmp_out_dir, html_out_file), |
| + '--js', os.path.join(tmp_out_dir, js_out_file)]) |
|
calamity
2017/07/19 06:15:33
If we move the polymer_css_build step into this sc
dpapad
2017/07/19 20:49:38
Acknowledged. As said in previous comment, prefer
|
| + |
| + # Move the HTML file to its final destination. |
| + shutil.copy(os.path.join(tmp_out_dir, html_out_file), out_path) |
| + |
| + # Pass the JS file through Uglify and write the output to its final |
| + # destination. |
| + node.RunNode([node_modules.PathToUglify(), |
| + os.path.join(tmp_out_dir, js_out_file), |
| + '--comments', '"/Copyright|license|LICENSE|\<\/?if/"', |
| + '--output', os.path.join(out_path, js_out_file)]) |
| finally: |
| - if os.path.exists(crisper_input.name): |
| - os.remove(crisper_input.name) |
| - if os.path.exists(crisper_output.name): |
| - os.remove(crisper_output.name) |
| + shutil.rmtree(tmp_out_dir) |
|
calamity
2017/07/19 06:15:33
If any of the commands here fail, will the build s
michaelpg
2017/07/19 18:51:59
Is it worth leaving the output files around (inste
dpapad
2017/07/19 20:49:38
The build still fails if any command fails.
If yo
michaelpg
2017/07/21 00:57:11
d'oh, yeah I saw "tmp" and thought it was a unique
|
| + return manifest_out_path |
| def main(argv): |
| @@ -203,11 +205,11 @@ def main(argv): |
| parser.add_argument('--depfile', required=True) |
| parser.add_argument('--exclude', nargs='*') |
| parser.add_argument('--host', required=True) |
| - parser.add_argument('--html_in_file', required=True) |
| - parser.add_argument('--html_out_file', required=True) |
| + parser.add_argument('--html_in_files', nargs='*', required=True) |
| + parser.add_argument('--html_out_files', nargs='*', required=True) |
| parser.add_argument('--input', required=True) |
| parser.add_argument('--insert_in_head') |
| - parser.add_argument('--js_out_file', required=True) |
| + parser.add_argument('--js_out_files', nargs='*', required=True) |
| parser.add_argument('--out_folder', required=True) |
| args = parser.parse_args(argv) |
| @@ -218,8 +220,20 @@ def main(argv): |
| args.input = os.path.normpath(args.input) |
| args.out_folder = os.path.normpath(args.out_folder) |
| - _vulcanize(args.input, args) |
| - _update_dep_file(args.input, args) |
| + manifest_out_path = _vulcanize(args.input, args) |
| + |
| + # Prior call to _vulcanize() generated an output manifest file, containing |
| + # information about all files that were bundled. Grab it from there. |
| + manifest = json.loads(open(manifest_out_path, 'r').read()) |
| + |
| + # polymer-bundler reports any missing files in the output manifest, instead of |
| + # directly failing. Ensure that no such files were encountered. |
| + if '_missing' in manifest: |
| + raise Exception( |
| + 'polymer-bundler could not find files for the following URLs:\n' + |
| + '\n'.join(manifest['_missing'])) |
| + |
| + _update_dep_file(args.input, args, manifest) |
| if __name__ == '__main__': |