Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: chrome/browser/resources/vulcanize_gn.py

Issue 2674553002: MD WebUI: attempt to clean up file paths on vulcanize+Windows (Closed)
Patch Set: tests Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2016 The Chromium Authors. All rights reserved. 2 # Copyright 2016 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 import argparse 6 import argparse
7 import itertools 7 import itertools
8 import os 8 import os
9 import platform 9 import platform
10 import re 10 import re
11 import subprocess 11 import subprocess
12 import sys 12 import sys
13 import tempfile 13 import tempfile
14 14
15 15
16 _HERE_PATH = os.path.dirname(__file__) 16 _HERE_PATH = os.path.dirname(__file__)
17 _SRC_PATH = os.path.normpath(os.path.join(_HERE_PATH, '..', '..', '..')) 17 _SRC_PATH = os.path.normpath(os.path.join(_HERE_PATH, '..', '..', '..'))
18 _CWD = os.getcwd() 18 _CWD = os.getcwd() # NOTE(dbeam): this is typically out/<gn_name>/.
19 19
20 sys.path.append(os.path.join(_SRC_PATH, 'third_party', 'node')) 20 sys.path.append(os.path.join(_SRC_PATH, 'third_party', 'node'))
21 import node 21 import node
22 import node_modules 22 import node_modules
23 23
24 24
25 _RESOURCES_PATH = os.path.join(_SRC_PATH, 'ui', 'webui', 'resources') 25 _RESOURCES_PATH = os.path.join(_SRC_PATH, 'ui', 'webui', 'resources')
26 26
27 27
28 _CR_ELEMENTS_PATH = os.path.join(_RESOURCES_PATH, 'cr_elements') 28 _CR_ELEMENTS_PATH = os.path.join(_RESOURCES_PATH, 'cr_elements')
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 print >> sys.stderr, '%s failed: %s' % (cmd, stderr) 89 print >> sys.stderr, '%s failed: %s' % (cmd, stderr)
90 raise 90 raise
91 91
92 return stdout 92 return stdout
93 93
94 94
95 def _undo_mapping(mappings, url): 95 def _undo_mapping(mappings, url):
96 for (redirect_url, file_path) in mappings: 96 for (redirect_url, file_path) in mappings:
97 if url.startswith(redirect_url): 97 if url.startswith(redirect_url):
98 return url.replace(redirect_url, file_path + os.sep) 98 return url.replace(redirect_url, file_path + os.sep)
99 # TODO(dbeam): can we make this stricter?
99 return url 100 return url
100 101
101 102
102 # Get a list of all files that were bundled with Vulcanize and update the 103 # Get a list of all files that were bundled with Vulcanize and update the
103 # depfile accordingly such that Ninja knows when to trigger re-vulcanization. 104 # depfile accordingly such that Ninja knows when to trigger re-vulcanization.
104 def _update_dep_file(in_folder, args): 105 def _update_dep_file(in_folder, args):
105 in_path = os.path.join(_CWD, in_folder) 106 in_path = os.path.join(_CWD, in_folder)
106 out_path = os.path.join(_CWD, args.out_folder) 107 out_path = os.path.join(_CWD, args.out_folder)
107 108
108 # Prior call to vulcanize already generated the deps list, grab it from there. 109 # Prior call to vulcanize already generated the deps list, grab it from there.
109 request_list = open(os.path.join( 110 request_list_path = os.path.join(out_path, _REQUEST_LIST_FILE)
110 out_path, _REQUEST_LIST_FILE), 'r').read().splitlines() 111 request_list = open(request_list_path, 'r').read().splitlines()
112
113 if platform.system() == 'Windows':
114 # TODO(dbeam): UGH. For some reason Vulcanize is interpreting the target
115 # file path as a URL and using the drive letter (e.g. D:\) as a protocol.
116 # This is a little insane, but we're fixing here by normalizing case (which
117 # really shouldn't matter, these are all file paths and generally are all
118 # lower case) and writing from / to \ (file path) and then back again. This
119 # is compounded by NodeJS having a bug in url.resolve() that handles
120 # chrome:// protocol URLs poorly as well as us using startswith() to strip
121 # file paths (which isn't crazy awesome either). Don't remove unless you
122 # really really know what you're doing.
123 norm = lambda u: u.lower().replace('/', '\\')
124 request_list = [norm(u).replace(norm(in_path), '').replace('\\', '/')
125 for u in request_list]
111 126
112 # Undo the URL mappings applied by vulcanize to get file paths relative to 127 # Undo the URL mappings applied by vulcanize to get file paths relative to
113 # current working directory. 128 # current working directory.
114 url_mappings = _URL_MAPPINGS + [ 129 url_mappings = _URL_MAPPINGS + [
115 ('/', os.path.relpath(in_path, _CWD)), 130 ('/', os.path.relpath(in_path, _CWD)),
116 ('chrome://%s/' % args.host, os.path.relpath(in_path, _CWD)), 131 ('chrome://%s/' % args.host, os.path.relpath(in_path, _CWD)),
117 ] 132 ]
118 133
119 dependencies = map( 134 deps = [_undo_mapping(url_mappings, u) for u in request_list]
120 lambda url: _undo_mapping(url_mappings, url), request_list) 135 deps = map(os.path.normpath, deps)
121 136
122 # If the input was a .pak file, the generated depfile should not list files 137 # If the input was a .pak file, the generated depfile should not list files
123 # already in the .pak file. 138 # already in the .pak file.
124 filtered_dependencies = dependencies 139 if args.input.endswith('.pak'):
125 if (args.input_type == 'PAK_FILE'):
126 filter_url = os.path.join(args.out_folder, _PAK_UNPACK_FOLDER) 140 filter_url = os.path.join(args.out_folder, _PAK_UNPACK_FOLDER)
127 filtered_dependencies = filter( 141 deps = [d for d in deps if not d.startswith(filter_url)]
128 lambda url: not url.startswith(filter_url), dependencies)
129 142
130 with open(os.path.join(_CWD, args.depfile), 'w') as f: 143 with open(os.path.join(_CWD, args.depfile), 'w') as f:
131 f.write(os.path.join( 144 deps_file_header = os.path.join(args.out_folder, args.html_out_file)
132 args.out_folder, args.html_out_file) + ': ' + ' '.join( 145 f.write(deps_file_header + ': ' + ' '.join(deps))
133 filtered_dependencies))
134 146
135 147
136 def _vulcanize(in_folder, args): 148 def _vulcanize(in_folder, args):
137 in_path = os.path.normpath(os.path.join(_CWD, in_folder)) 149 in_path = os.path.normpath(os.path.join(_CWD, in_folder))
138 out_path = os.path.join(_CWD, args.out_folder) 150 out_path = os.path.join(_CWD, args.out_folder)
139 151
140 html_out_path = os.path.join(out_path, args.html_out_file) 152 html_out_path = os.path.join(out_path, args.html_out_file)
141 js_out_path = os.path.join(out_path, args.js_out_file) 153 js_out_path = os.path.join(out_path, args.js_out_file)
142 154
143 output = _run_node( 155 output = _run_node(
144 [node_modules.PathToVulcanize()] + 156 [node_modules.PathToVulcanize()] +
145 _VULCANIZE_BASE_ARGS + _VULCANIZE_REDIRECT_ARGS + 157 _VULCANIZE_BASE_ARGS + _VULCANIZE_REDIRECT_ARGS +
146 ['--out-request-list', os.path.join(out_path, _REQUEST_LIST_FILE), 158 ['--out-request-list', os.path.join(out_path, _REQUEST_LIST_FILE),
147 '--redirect', '"/|%s"' % in_path, 159 '--redirect', '"/|%s"' % in_path,
148 '--redirect', '"chrome://%s/|%s"' % (args.host, in_path), 160 '--redirect', '"chrome://%s/|%s"' % (args.host, in_path),
149 # TODO(dpapad): Figure out why vulcanize treats the input path 161 # TODO(dpapad): Figure out why vulcanize treats the input path
150 # differently on Windows VS Linux/Mac. 162 # differently on Windows VS Linux/Mac.
151 os.path.join( 163 os.path.join(
152 in_path if platform.system() == 'Windows' else os.sep, 164 in_path if platform.system() == 'Windows' else os.sep,
153 args.html_in_file)]) 165 args.html_in_file)])
154 166
155 # Grit includes are not supported, use HTML imports instead. 167 # Grit includes are not supported, use HTML imports instead.
156 output = output.replace('<include src="', '<include src-disabled="') 168 output = output.replace('<include src="', '<include src-disabled="')
157 169
158 if args.insert_in_head: 170 if args.insert_in_head:
159 assert '<head>' in output 171 assert '<head>' in output
172 # NOTE(dbeam): Vulcanize eats <base> tags after processing. This undoes
173 # that by adding a <base> tag to the (post-processed) generated output.
160 output = output.replace('<head>', '<head>' + args.insert_in_head) 174 output = output.replace('<head>', '<head>' + args.insert_in_head)
161 175
162 with tempfile.NamedTemporaryFile(mode='wt+', delete=False) as tmp: 176 with tempfile.NamedTemporaryFile(mode='wt+', delete=False) as tmp:
163 tmp.write(output) 177 tmp.write(output)
164 178
165 try: 179 try:
166 _run_node([node_modules.PathToCrisper(), 180 _run_node([node_modules.PathToCrisper(),
167 '--source', tmp.name, 181 '--source', tmp.name,
168 '--script-in-head', 'false', 182 '--script-in-head', 'false',
169 '--html', html_out_path, 183 '--html', html_out_path,
170 '--js', js_out_path]) 184 '--js', js_out_path])
171 185
172 # TODO(tsergeant): Remove when JS resources are minified by default: 186 # TODO(tsergeant): Remove when JS resources are minified by default:
173 # crbug.com/619091. 187 # crbug.com/619091.
174 _run_node([node_modules.PathToUglifyJs(), js_out_path, 188 _run_node([node_modules.PathToUglifyJs(), js_out_path,
175 '--comments', '"/Copyright|license|LICENSE|\<\/?if/"', 189 '--comments', '"/Copyright|license|LICENSE|\<\/?if/"',
176 '--output', js_out_path]) 190 '--output', js_out_path])
177 finally: 191 finally:
178 os.remove(tmp.name) 192 os.remove(tmp.name)
179 193
180 194
181 def _css_build(out_folder, files): 195 def _css_build(out_folder, files):
182 out_path = os.path.join(_CWD, out_folder) 196 out_path = os.path.join(_CWD, out_folder)
183 paths = map(lambda f: os.path.join(out_path, f), files) 197 paths = [os.path.join(out_path, f) for f in files]
184 198
185 _run_node([node_modules.PathToPolymerCssBuild()] + paths) 199 _run_node([node_modules.PathToPolymerCssBuild()] + paths)
186 200
187 201
188 def main(): 202 def main(argv):
189 parser = argparse.ArgumentParser() 203 parser = argparse.ArgumentParser()
190 parser.add_argument('--depfile') 204 parser.add_argument('--depfile')
dpapad 2017/02/07 03:00:32 This is required too. If it needs to be optional t
Dan Beam 2017/02/07 03:02:39 made required
191 parser.add_argument('--host') 205 parser.add_argument('--host', required=True)
192 parser.add_argument('--html_in_file') 206 parser.add_argument('--html_in_file', required=True)
193 parser.add_argument('--html_out_file') 207 parser.add_argument('--html_out_file', required=True)
194 parser.add_argument('--input') 208 parser.add_argument('--input', required=True)
195 parser.add_argument('--input_type')
196 parser.add_argument('--insert_in_head') 209 parser.add_argument('--insert_in_head')
197 parser.add_argument('--js_out_file') 210 parser.add_argument('--js_out_file', required=True)
198 parser.add_argument('--out_folder') 211 parser.add_argument('--out_folder', required=True)
199 args = parser.parse_args() 212 args = parser.parse_args(argv)
213
214 # NOTE(dbeam): on Windows, GN can send dirs/like/this. When joined, you might
215 # get dirs/like/this\file.txt. This looks odd to windows. Normalize to right
216 # the slashes.
217 if args.depfile:
218 args.depfile = os.path.normpath(args.depfile)
200 args.input = os.path.normpath(args.input) 219 args.input = os.path.normpath(args.input)
220 args.out_folder = os.path.normpath(args.out_folder)
201 221
202 vulcanize_input_folder = args.input 222 vulcanize_input_folder = args.input
203 223
204 # If a .pak file was specified, unpack that file first and pass the output to 224 # If a .pak file was specified, unpack that file first and pass the output to
205 # vulcanize. 225 # vulcanize.
206 if (args.input_type == 'PAK_FILE'): 226 if args.input.endswith('.pak'):
207 import unpack_pak 227 import unpack_pak
208 input_folder = os.path.join(_CWD, args.input) 228 input_folder = os.path.join(_CWD, args.input)
209 output_folder = os.path.join(args.out_folder, _PAK_UNPACK_FOLDER) 229 output_folder = os.path.join(args.out_folder, _PAK_UNPACK_FOLDER)
210 unpack_pak.unpack(args.input, output_folder) 230 unpack_pak.unpack(args.input, output_folder)
211 vulcanize_input_folder = output_folder 231 vulcanize_input_folder = output_folder
212 232
213 _vulcanize(vulcanize_input_folder, args) 233 _vulcanize(vulcanize_input_folder, args)
214 _css_build(args.out_folder, files=[args.html_out_file]) 234 _css_build(args.out_folder, files=[args.html_out_file])
215 235
216 _update_dep_file(vulcanize_input_folder, args) 236 if args.depfile:
237 _update_dep_file(vulcanize_input_folder, args)
217 238
218 239
219 if __name__ == '__main__': 240 if __name__ == '__main__':
220 main() 241 main(sys.argv[1:])
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698