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

Side by Side Diff: Source/devtools/scripts/concatenate_application_code.py

Issue 646413002: DevTools: Refactor build script to copy module files in debug_devtools mode (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Comments addressed, GN fixed, obsolete file removed Created 6 years, 2 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 | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # 2 #
3 # Copyright 2014 The Chromium Authors. All rights reserved. 3 # Copyright 2014 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 """ 7 """
8 Concatenates autostart modules, application modules' module.json descriptors, 8 Release:
9 and the application loader into a single script. 9 - Concatenates autostart modules, application modules' module.json descriptors ,
10 Also concatenates all workers' dependencies into individual worker loader script s. 10 and the application loader into a single script.
11 - Concatenates all workers' dependencies into individual worker loader scripts .
12 - Builds app.html referencing the application script.
13 Debug:
14 - Copies the module directories into their destinations.
15 - Copies app.html as-is.
11 """ 16 """
12 17
13 from cStringIO import StringIO 18 from cStringIO import StringIO
14 from os import path 19 from os import path
15 from modular_build import read_file, write_file, bail_error 20 from modular_build import read_file, write_file, bail_error
16 import copy 21 import copy
17 import modular_build 22 import modular_build
18 import os 23 import os
19 import re 24 import re
25 import shutil
20 import sys 26 import sys
21 27
22 try: 28 try:
23 import simplejson as json 29 import simplejson as json
24 except ImportError: 30 except ImportError:
25 import json 31 import json
26 32
27 rjsmin_path = os.path.abspath(os.path.join( 33 rjsmin_path = os.path.abspath(os.path.join(
28 os.path.dirname(__file__), 34 os.path.dirname(__file__),
29 "..", 35 "..",
30 "..", 36 "..",
31 "build", 37 "build",
32 "scripts")) 38 "scripts"))
33 sys.path.append(rjsmin_path) 39 sys.path.append(rjsmin_path)
34 import rjsmin 40 import rjsmin
35 41
36 42
37 def minify_if_needed(javascript, minify): 43 def minify_js(javascript):
38 return rjsmin.jsmin(javascript) if minify else javascript 44 return rjsmin.jsmin(javascript)
39 45
40 46
41 def concatenated_module_filename(module_name, output_dir): 47 def concatenated_module_filename(module_name, output_dir):
42 return path.join(output_dir, module_name + '_module.js') 48 return path.join(output_dir, module_name + '_module.js')
43 49
44 50
45 def concatenate_autostart_modules(descriptors, application_dir, output_dir, outp ut): 51 def hardlink_or_copy_dir(src, dest):
46 non_autostart = set() 52 if path.exists(dest):
47 sorted_module_names = descriptors.sorted_modules() 53 shutil.rmtree(dest)
48 for name in sorted_module_names: 54 os.mkdir(dest)
49 desc = descriptors.modules[name] 55 for root, dirs, files in os.walk(src):
50 name = desc['name'] 56 for name in files:
51 type = descriptors.application[name].get('type') 57 src_name = path.join(root, name)
52 if type == 'autostart': 58 dest_name = path.join(dest, path.join(path.relpath(src, root), name) )
dgozman 2014/10/14 09:21:08 Shouldn't this be |relpath(root, src)| ?
apavlov 2014/10/14 10:02:58 Yes, refactored the entire snippet and tested on n
53 deps = set(desc.get('dependencies', [])) 59 if hasattr(os, 'link'):
54 non_autostart_deps = deps & non_autostart 60 os.link(src_name, dest_name)
55 if len(non_autostart_deps): 61 else:
56 bail_error('Non-autostart dependencies specified for the autosta rted module "%s": %s' % (name, non_autostart_deps)) 62 shutil.copy(src_name, dest_name)
dgozman 2014/10/14 09:21:08 Will this create necessary directories? I think yo
apavlov 2014/10/14 10:02:58 Ah, right, this was supposed to be handled by the
57 output.write('\n/* Module %s */\n' % name)
58 modular_build.concatenate_scripts(desc.get('scripts'), path.join(app lication_dir, name), output_dir, output)
59 elif type != 'worker':
60 non_autostart.add(name)
61 63
62 64
63 def concatenate_application_script(application_name, descriptors, application_di r, output_dir, minify): 65 class AppBuilder:
64 application_loader_name = application_name + '.js' 66 def __init__(self, application_name, descriptors, application_dir, output_di r):
65 output = StringIO() 67 self.application_name = application_name
66 runtime_contents = read_file(path.join(application_dir, 'Runtime.js')) 68 self.descriptors = descriptors
67 runtime_contents = re.sub('var allDescriptors = \[\];', 'var allDescriptors = %s;' % release_module_descriptors(descriptors.modules).replace("\\", "\\\\"), runtime_contents, 1) 69 self.application_dir = application_dir
68 output.write('/* Runtime.js */\n') 70 self.output_dir = output_dir
69 output.write(runtime_contents)
70 output.write('\n/* Autostart modules */\n')
71 concatenate_autostart_modules(descriptors, application_dir, output_dir, outp ut)
72 output.write('/* Application descriptor %s */\n' % (application_name + '.jso n'))
73 output.write('applicationDescriptor = ')
74 output.write(descriptors.application_json)
75 output.write(';\n/* Application loader */\n')
76 output.write(read_file(path.join(application_dir, application_loader_name)))
77 71
78 write_file(path.join(output_dir, application_loader_name), minify_if_needed( output.getvalue(), minify)) 72 def app_file(self, extension):
79 output.close() 73 return self.application_name + '.' + extension
80 74
81 75
82 def concatenate_dynamic_module(module_name, descriptors, application_dir, output _dir, minify): 76 # Outputs:
83 scripts = descriptors.modules[module_name].get('scripts') 77 # <app_name>.html
84 if not scripts: 78 # <app_name>.js
85 return 79 # <module_name>_module.js
86 module_dir = path.join(application_dir, module_name) 80 class ReleaseBuilder(AppBuilder):
87 output = StringIO() 81 def __init__(self, application_name, descriptors, application_dir, output_di r):
88 modular_build.concatenate_scripts(scripts, module_dir, output_dir, output) 82 AppBuilder.__init__(self, application_name, descriptors, application_dir , output_dir)
89 output_file_path = concatenated_module_filename(module_name, output_dir) 83
90 write_file(output_file_path, minify_if_needed(output.getvalue(), minify)) 84 def build_app(self):
91 output.close() 85 self._build_html()
86 self._build_app_script()
87 for module in filter(lambda desc: not desc.get('type'), self.descriptors .application.values()):
88 self._concatenate_dynamic_module(module['name'])
89 for module in filter(lambda desc: desc.get('type') == 'worker', self.des criptors.application.values()):
90 self._concatenate_worker(module['name'])
91
92 def _build_html(self):
93 html_name = self.app_file('html')
94 output = StringIO()
95 with open(path.join(self.application_dir, html_name), 'r') as app_input_ html:
96 for line in app_input_html:
97 if '<script ' in line or '<link ' in line:
98 continue
99 if '</head>' in line:
100 output.write(self._generate_include_tag("%s.css" % self.appl ication_name))
101 output.write(self._generate_include_tag("%s.js" % self.appli cation_name))
102 output.write(line)
103
104 write_file(path.join(self.output_dir, html_name), output.getvalue())
105 output.close()
106
107 def _build_app_script(self):
108 script_name = self.app_file('js')
109 output = StringIO()
110 self._concatenate_application_script(output)
111 write_file(path.join(self.output_dir, script_name), output.getvalue())
dgozman 2014/10/14 09:21:08 Are you missing minify_js call here?
apavlov 2014/10/14 10:02:58 Done.
112 output.close()
113
114 def _generate_include_tag(self, resource_path):
115 if (resource_path.endswith('.js')):
116 return ' <script type="text/javascript" src="%s"></script>\n' % r esource_path
117 elif (resource_path.endswith('.css')):
118 return ' <link rel="stylesheet" type="text/css" href="%s">\n' % r esource_path
119 else:
120 assert resource_path
121
122 def _release_module_descriptors(self):
123 module_descriptors = self.descriptors.modules
124 result = []
125 for name in module_descriptors:
126 module = copy.copy(module_descriptors[name])
127 # Clear scripts, as they are not used at runtime
128 # (only the fact of their presence is important).
129 if module.get('scripts'):
130 module['scripts'] = []
131 result.append(module)
132 return json.dumps(result)
133
134 def _concatenate_autostart_modules(self, output):
135 non_autostart = set()
136 sorted_module_names = self.descriptors.sorted_modules()
137 for name in sorted_module_names:
138 desc = self.descriptors.modules[name]
139 name = desc['name']
140 type = self.descriptors.application[name].get('type')
141 if type == 'autostart':
142 deps = set(desc.get('dependencies', []))
143 non_autostart_deps = deps & non_autostart
144 if len(non_autostart_deps):
145 bail_error('Non-autostart dependencies specified for the aut ostarted module "%s": %s' % (name, non_autostart_deps))
146 output.write('\n/* Module %s */\n' % name)
147 modular_build.concatenate_scripts(desc.get('scripts'), path.join (self.application_dir, name), self.output_dir, output)
148 elif type != 'worker':
149 non_autostart.add(name)
150
151 def _concatenate_application_script(self, output):
152 application_loader_name = self.app_file('js')
153 runtime_contents = read_file(path.join(self.application_dir, 'Runtime.js '))
154 runtime_contents = re.sub('var allDescriptors = \[\];', 'var allDescript ors = %s;' % self._release_module_descriptors().replace("\\", "\\\\"), runtime_c ontents, 1)
155 output.write('/* Runtime.js */\n')
156 output.write(runtime_contents)
157 output.write('\n/* Autostart modules */\n')
158 self._concatenate_autostart_modules(output)
159 output.write('/* Application descriptor %s */\n' % self.app_file('json') )
160 output.write('applicationDescriptor = ')
161 output.write(self.descriptors.application_json)
162 output.write('\n/* Application loader */\n')
163 output.write(read_file(path.join(self.application_dir, application_loade r_name)))
164
165 def _concatenate_dynamic_module(self, module_name):
166 module = self.descriptors.modules[module_name]
167 scripts = module.get('scripts')
168 if not scripts:
169 return
170 module_dir = path.join(self.application_dir, module_name)
171 output = StringIO()
172 modular_build.concatenate_scripts(scripts, module_dir, self.output_dir, output)
173 output_file_path = concatenated_module_filename(module_name, self.output _dir)
174 write_file(output_file_path, minify_js(output.getvalue()))
175 output.close()
176
177 def _concatenate_worker(self, module_name):
178 descriptor = self.descriptors.modules[module_name]
179 scripts = descriptor.get('scripts')
180 if not scripts:
181 return
182
183 output = StringIO()
184 output.write('/* Worker %s */\n' % module_name)
185 dep_descriptors = []
186 for dep_name in self.descriptors.sorted_dependencies_closure(module_name ):
187 dep_descriptor = self.descriptors.modules[dep_name]
188 dep_descriptors.append(dep_descriptor)
189 scripts = dep_descriptor.get('scripts')
190 if scripts:
191 output.write('\n/* Module %s */\n' % dep_name)
192 modular_build.concatenate_scripts(scripts, path.join(self.applic ation_dir, dep_name), self.output_dir, output)
193
194 output_file_path = concatenated_module_filename(module_name, self.output _dir)
195 write_file(output_file_path, minify_js(output.getvalue()))
196 output.close()
92 197
93 198
94 def concatenate_worker(module_name, descriptors, application_dir, output_dir, mi nify): 199 # Outputs:
95 descriptor = descriptors.modules[module_name] 200 # <app_name>.html as-is
96 scripts = descriptor.get('scripts') 201 # <app_name>.js as-is
97 if not scripts: 202 # <module_name>/<all_files>
98 return 203 class DebugBuilder(AppBuilder):
99 worker_dir = path.join(application_dir, module_name) 204 def __init__(self, application_name, descriptors, application_dir, output_di r):
100 output_file_path = concatenated_module_filename(module_name, output_dir) 205 AppBuilder.__init__(self, application_name, descriptors, application_dir , output_dir)
101 206
102 output = StringIO() 207 def build_app(self):
103 output.write('/* Worker %s */\n' % module_name) 208 self._build_html()
104 dependencies = descriptors.sorted_dependencies_closure(module_name) 209 shutil.copy(path.join(self.application_dir, self.app_file('js')), self.o utput_dir)
105 dep_descriptors = [] 210 for module_name in self.descriptors.modules:
106 for dep_name in dependencies: 211 print module_name
107 dep_descriptor = descriptors.modules[dep_name] 212 module = self.descriptors.modules[module_name]
108 dep_descriptors.append(dep_descriptor) 213 input_module_dir = path.join(self.application_dir, module_name)
109 scripts = dep_descriptor.get('scripts') 214 output_module_dir = path.join(self.output_dir, module_name)
110 if scripts: 215 hardlink_or_copy_dir(input_module_dir, output_module_dir)
111 output.write('\n/* Module %s */\n' % dep_name)
112 modular_build.concatenate_scripts(scripts, path.join(application_dir , dep_name), output_dir, output)
113 216
114 write_file(output_file_path, minify_if_needed(output.getvalue(), minify)) 217 def _build_html(self):
115 output.close() 218 html_name = self.app_file('html')
219 output = StringIO()
220 with open(path.join(self.application_dir, html_name), 'r') as app_input_ html:
221 for line in app_input_html:
222 output.write(line)
223
224 write_file(path.join(self.output_dir, html_name), output.getvalue())
225 output.close()
116 226
117 227
118 def release_module_descriptors(module_descriptors): 228 def build_application(application_name, loader, application_dir, output_dir, rel ease_mode):
119 result = []
120 for name in module_descriptors:
121 module = copy.copy(module_descriptors[name])
122 # Clear scripts, as they are not used at runtime
123 # (only the fact of their presence is important).
124 if module.get('scripts'):
125 module['scripts'] = []
126 result.append(module)
127 return json.dumps(result)
128
129
130 def build_application(application_name, loader, application_dir, output_dir, min ify):
131 descriptors = loader.load_application(application_name + '.json') 229 descriptors = loader.load_application(application_name + '.json')
132 concatenate_application_script(application_name, descriptors, application_di r, output_dir, minify) 230 if release_mode:
133 for module in filter(lambda desc: not desc.get('type'), descriptors.applicat ion.values()): 231 builder = ReleaseBuilder(application_name, descriptors, application_dir, output_dir)
134 concatenate_dynamic_module(module['name'], descriptors, application_dir, output_dir, minify) 232 else:
135 for module in filter(lambda desc: desc.get('type') == 'worker', descriptors. application.values()): 233 builder = DebugBuilder(application_name, descriptors, application_dir, o utput_dir)
136 concatenate_worker(module['name'], descriptors, application_dir, output_ dir, minify) 234 builder.build_app()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698