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

Side by Side Diff: mojo/public/tools/dart_pkg.py

Issue 1259873002: Dart: Runs dartanalyzer for the dart_pkg build rule. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 4 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
zra 2015/07/27 16:27:46 Changed 4 -> 2 space indents. Actual changes noted
Cutch 2015/07/27 16:31:50 https://google-styleguide.googlecode.com/svn/trunk
2 # 2 #
3 # Copyright 2015 The Chromium Authors. All rights reserved. 3 # Copyright 2015 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 """Utility for dart_pkg and dart_pkg_app rules""" 7 """Utility for dart_pkg and dart_pkg_app rules"""
8 8
9 import argparse 9 import argparse
10 import errno 10 import errno
11 import json 11 import json
12 import os 12 import os
13 import shutil 13 import shutil
14 import subprocess
14 import sys 15 import sys
15 16
16 # Disable lint check for finding modules: 17 # Disable lint check for finding modules:
17 # pylint: disable=F0401 18 # pylint: disable=F0401
18 19
19 sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), 20 sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
20 "bindings/pylib")) 21 "bindings/pylib"))
21 22
22 from mojom.parse.parser import Parse 23 from mojom.parse.parser import Parse
23 from mojom.parse.translate import Translate 24 from mojom.parse.translate import Translate
24 25
25 USE_LINKS = sys.platform != "win32" 26 USE_LINKS = sys.platform != "win32"
26 27
28 DART_ANALYZE = os.path.join(os.path.dirname(os.path.abspath(__file__)),
29 "dart_analyze.py")
27 30
28 def mojom_dart_filter(path): 31 def mojom_dart_filter(path):
29 if os.path.isdir(path): 32 if os.path.isdir(path):
30 return True 33 return True
31 # Don't include all .dart, just .mojom.dart. 34 # Don't include all .dart, just .mojom.dart.
32 return path.endswith('.mojom.dart') 35 return path.endswith('.mojom.dart')
33 36
34 37
35 def dart_filter(path): 38 def dart_filter(path):
36 if os.path.isdir(path): 39 if os.path.isdir(path):
37 return True 40 return True
38 _, ext = os.path.splitext(path) 41 _, ext = os.path.splitext(path)
39 # .dart includes '.mojom.dart' 42 # .dart includes '.mojom.dart'
40 return ext == '.dart' 43 return ext == '.dart'
41 44
42 45
43 def mojom_filter(path): 46 def mojom_filter(path):
44 if os.path.isdir(path): 47 if os.path.isdir(path):
45 return True 48 return True
46 _, ext = os.path.splitext(path) 49 _, ext = os.path.splitext(path)
47 return ext == '.mojom' 50 return ext == '.mojom'
48 51
49 52
50 def ensure_dir_exists(path): 53 def ensure_dir_exists(path):
51 abspath = os.path.abspath(path) 54 abspath = os.path.abspath(path)
52 if not os.path.exists(abspath): 55 if not os.path.exists(abspath):
53 os.makedirs(abspath) 56 os.makedirs(abspath)
54 57
55 58
56 def has_pubspec_yaml(paths): 59 def has_pubspec_yaml(paths):
57 for path in paths: 60 for path in paths:
58 _, filename = os.path.split(path) 61 _, filename = os.path.split(path)
59 if 'pubspec.yaml' == filename: 62 if 'pubspec.yaml' == filename:
60 return True 63 return True
61 return False 64 return False
62 65
63 66
64 def link(from_root, to_root): 67 def link(from_root, to_root):
68 ensure_dir_exists(os.path.dirname(to_root))
69 if os.path.exists(to_root):
70 os.unlink(to_root)
71 try:
72 os.symlink(from_root, to_root)
73 except OSError as e:
74 if e.errno == errno.EEXIST:
75 pass
76
77
78 def copy(from_root, to_root, filter_func=None):
79 if not os.path.exists(from_root):
80 return
81 if os.path.isfile(from_root):
65 ensure_dir_exists(os.path.dirname(to_root)) 82 ensure_dir_exists(os.path.dirname(to_root))
66 if os.path.exists(to_root): 83 shutil.copy(from_root, to_root)
67 os.unlink(to_root) 84 return
68 try: 85
69 os.symlink(from_root, to_root) 86 ensure_dir_exists(to_root)
70 except OSError as e: 87
71 if e.errno == errno.EEXIST: 88 for root, dirs, files in os.walk(from_root):
72 pass 89 # filter_func expects paths not names, so wrap it to make them absolute.
73 90 wrapped_filter = None
74 91 if filter_func:
75 def copy(from_root, to_root, filter_func=None): 92 wrapped_filter = lambda name: filter_func(os.path.join(root, name))
76 if not os.path.exists(from_root): 93
77 return 94 for name in filter(wrapped_filter, files):
78 if os.path.isfile(from_root): 95 from_path = os.path.join(root, name)
79 ensure_dir_exists(os.path.dirname(to_root)) 96 root_rel_path = os.path.relpath(from_path, from_root)
80 shutil.copy(from_root, to_root) 97 to_path = os.path.join(to_root, root_rel_path)
81 return 98 to_dir = os.path.dirname(to_path)
82 99 if not os.path.exists(to_dir):
83 ensure_dir_exists(to_root) 100 os.makedirs(to_dir)
84 101 shutil.copy(from_path, to_path)
85 for root, dirs, files in os.walk(from_root): 102
86 # filter_func expects paths not names, so wrap it to make them absolute. 103 dirs[:] = filter(wrapped_filter, dirs)
87 wrapped_filter = None
88 if filter_func:
89 wrapped_filter = lambda name: filter_func(os.path.join(root, name))
90
91 for name in filter(wrapped_filter, files):
92 from_path = os.path.join(root, name)
93 root_rel_path = os.path.relpath(from_path, from_root)
94 to_path = os.path.join(to_root, root_rel_path)
95 to_dir = os.path.dirname(to_path)
96 if not os.path.exists(to_dir):
97 os.makedirs(to_dir)
98 shutil.copy(from_path, to_path)
99
100 dirs[:] = filter(wrapped_filter, dirs)
101 104
102 105
103 def copy_or_link(from_root, to_root, filter_func=None): 106 def copy_or_link(from_root, to_root, filter_func=None):
104 if USE_LINKS: 107 if USE_LINKS:
105 link(from_root, to_root) 108 link(from_root, to_root)
106 else: 109 else:
107 copy(from_root, to_root, filter_func) 110 copy(from_root, to_root, filter_func)
108 111
109 112
110 def remove_if_exists(path): 113 def remove_if_exists(path):
111 try: 114 try:
112 os.remove(path) 115 os.remove(path)
113 except OSError as e: 116 except OSError as e:
114 if e.errno != errno.ENOENT: 117 if e.errno != errno.ENOENT:
115 raise 118 raise
116 119
117 def list_files(from_root, filter_func=None): 120 def list_files(from_root, filter_func=None):
118 file_list = [] 121 file_list = []
119 for root, dirs, files in os.walk(from_root): 122 for root, dirs, files in os.walk(from_root):
120 # filter_func expects paths not names, so wrap it to make them absolute. 123 # filter_func expects paths not names, so wrap it to make them absolute.
121 wrapped_filter = None 124 wrapped_filter = None
122 if filter_func: 125 if filter_func:
123 wrapped_filter = lambda name: filter_func(os.path.join(root, name)) 126 wrapped_filter = lambda name: filter_func(os.path.join(root, name))
124 for name in filter(wrapped_filter, files): 127 for name in filter(wrapped_filter, files):
125 path = os.path.join(root, name) 128 path = os.path.join(root, name)
126 file_list.append(path) 129 file_list.append(path)
127 dirs[:] = filter(wrapped_filter, dirs) 130 dirs[:] = filter(wrapped_filter, dirs)
128 return file_list 131 return file_list
129 132
130 133
131 def remove_broken_symlink(path): 134 def remove_broken_symlink(path):
132 try: 135 try:
133 link_path = os.readlink(path) 136 link_path = os.readlink(path)
134 except OSError as e: 137 except OSError as e:
135 # Path was not a symlink. 138 # Path was not a symlink.
136 if e.errno == errno.EINVAL: 139 if e.errno == errno.EINVAL:
137 pass 140 pass
138 else: 141 else:
139 if not os.path.exists(link_path): 142 if not os.path.exists(link_path):
140 os.unlink(path) 143 os.unlink(path)
141 144
142 145
143 def remove_broken_symlinks(root_dir): 146 def remove_broken_symlinks(root_dir):
144 for current_dir, _, child_files in os.walk(root_dir): 147 for current_dir, _, child_files in os.walk(root_dir):
145 for filename in child_files: 148 for filename in child_files:
146 path = os.path.join(current_dir, filename) 149 path = os.path.join(current_dir, filename)
147 remove_broken_symlink(path) 150 remove_broken_symlink(path)
148 151
149 152
150 def mojom_path(filename): 153 def mojom_path(filename):
151 with open(filename) as f: 154 with open(filename) as f:
152 source = f.read() 155 source = f.read()
153 tree = Parse(source, filename) 156 tree = Parse(source, filename)
154 _, name = os.path.split(filename) 157 _, name = os.path.split(filename)
155 mojom = Translate(tree, name) 158 mojom = Translate(tree, name)
156 elements = mojom['namespace'].split('.') 159 elements = mojom['namespace'].split('.')
157 elements.append("%s" % mojom['name']) 160 elements.append("%s" % mojom['name'])
158 return os.path.join(*elements) 161 return os.path.join(*elements)
162
163
164 def analyze_entrypoints(dart_sdk, package_root, entrypoints):
zra 2015/07/27 16:27:46 New function for invoking dart_analyze.py
165 cmd = [ "python", DART_ANALYZE ]
166 cmd.append("--dart-sdk")
167 cmd.append(dart_sdk)
168 cmd.append("--entrypoints")
169 cmd.extend(entrypoints)
170 cmd.append("--package-root")
171 cmd.append(package_root)
172 cmd.append("--no-hints")
173 try:
174 subprocess.check_call(cmd)
175 except subprocess.CalledProcessError as e:
176 return e.returncode
177 return 0
159 178
160 179
161 def main(): 180 def main():
162 parser = argparse.ArgumentParser(description='Generate a dart-pkg') 181 parser = argparse.ArgumentParser(description='Generate a dart-pkg')
163 parser.add_argument('--package-name', 182 parser.add_argument('--dart-sdk',
zra 2015/07/27 16:27:46 New option for Dart SDK location.
164 action='store', 183 action='store',
165 type=str, 184 metavar='dart_sdk',
166 metavar='package_name', 185 help='Path to the Dart SDK.')
167 help='Name of package', 186 parser.add_argument('--package-name',
168 required=True) 187 action='store',
169 parser.add_argument('--gen-directory', 188 metavar='package_name',
170 metavar='gen_directory', 189 help='Name of package',
171 help="dart-gen directory", 190 required=True)
172 required=True) 191 parser.add_argument('--gen-directory',
173 parser.add_argument('--pkg-directory', 192 metavar='gen_directory',
174 metavar='pkg_directory', 193 help="dart-gen directory",
175 help='Directory where dart_pkg should go', 194 required=True)
176 required=True) 195 parser.add_argument('--pkg-directory',
177 parser.add_argument('--package-root', 196 metavar='pkg_directory',
178 metavar='package_root', 197 help='Directory where dart_pkg should go',
179 help='packages/ directory', 198 required=True)
180 required=True) 199 parser.add_argument('--package-root',
181 parser.add_argument('--stamp-file', 200 metavar='package_root',
182 metavar='stamp_file', 201 help='packages/ directory',
183 help='timestamp file', 202 required=True)
184 required=True) 203 parser.add_argument('--stamp-file',
185 parser.add_argument('--package-sources', 204 metavar='stamp_file',
186 metavar='package_sources', 205 help='timestamp file',
187 help='Package sources', 206 required=True)
188 nargs='+') 207 parser.add_argument('--package-sources',
189 parser.add_argument('--mojom-sources', 208 metavar='package_sources',
190 metavar='mojom_sources', 209 help='Package sources',
191 help='.mojom and .mojom.dart sources', 210 nargs='+')
192 nargs='*', 211 parser.add_argument('--package-entrypoints',
zra 2015/07/27 16:27:46 New option for entrypoints.
193 default=[]) 212 metavar='package_entrypoints',
194 parser.add_argument('--sdk-ext-directories', 213 help='Package entry points for analyzer',
195 metavar='sdk_ext_directories', 214 nargs='*',
196 help='Directory containing .dart sources', 215 default=[])
197 nargs='*', 216 parser.add_argument('--mojom-sources',
198 default=[]) 217 metavar='mojom_sources',
199 parser.add_argument('--sdk-ext-files', 218 help='.mojom and .mojom.dart sources',
200 metavar='sdk_ext_files', 219 nargs='*',
201 help='List of .dart files that are part of of sdk_ext.', 220 default=[])
202 nargs='*', 221 parser.add_argument('--sdk-ext-directories',
203 default=[]) 222 metavar='sdk_ext_directories',
204 parser.add_argument('--sdk-ext-mappings', 223 help='Directory containing .dart sources',
205 metavar='sdk_ext_mappings', 224 nargs='*',
206 help='Mappings for SDK extension libraries.', 225 default=[])
207 nargs='*', 226 parser.add_argument('--sdk-ext-files',
208 default=[]) 227 metavar='sdk_ext_files',
209 args = parser.parse_args() 228 help='List of .dart files that are part of of sdk_ext.',
210 229 nargs='*',
211 # We must have a pubspec.yaml. 230 default=[])
212 assert has_pubspec_yaml(args.package_sources) 231 parser.add_argument('--sdk-ext-mappings',
213 232 metavar='sdk_ext_mappings',
214 target_dir = os.path.join(args.pkg_directory, args.package_name) 233 help='Mappings for SDK extension libraries.',
215 lib_path = os.path.join(target_dir, "lib") 234 nargs='*',
216 235 default=[])
217 mappings = {} 236 args = parser.parse_args()
218 for mapping in args.sdk_ext_mappings: 237
219 library, path = mapping.split(',', 1) 238 # We must have a pubspec.yaml.
220 mappings[library] = '../sdk_ext/%s' % path 239 assert has_pubspec_yaml(args.package_sources)
221 240
222 sdkext_path = os.path.join(lib_path, '_sdkext') 241 target_dir = os.path.join(args.pkg_directory, args.package_name)
223 if mappings: 242 lib_path = os.path.join(target_dir, "lib")
224 ensure_dir_exists(lib_path) 243
225 with open(sdkext_path, 'w') as stream: 244 mappings = {}
226 json.dump(mappings, stream, sort_keys=True, 245 for mapping in args.sdk_ext_mappings:
227 indent=2, separators=(',', ': ')) 246 library, path = mapping.split(',', 1)
228 else: 247 mappings[library] = '../sdk_ext/%s' % path
229 remove_if_exists(sdkext_path) 248
230 249 sdkext_path = os.path.join(lib_path, '_sdkext')
231 # Copy or symlink package sources into pkg directory. 250 if mappings:
232 common_source_prefix = os.path.commonprefix(args.package_sources) 251 ensure_dir_exists(lib_path)
233 for source in args.package_sources: 252 with open(sdkext_path, 'w') as stream:
234 relative_source = os.path.relpath(source, common_source_prefix) 253 json.dump(mappings, stream, sort_keys=True,
235 target = os.path.join(target_dir, relative_source) 254 indent=2, separators=(',', ': '))
236 copy_or_link(source, target) 255 else:
237 256 remove_if_exists(sdkext_path)
238 # Copy sdk-ext sources into pkg directory 257
239 sdk_ext_dir = os.path.join(target_dir, 'sdk_ext') 258 # Copy or symlink package sources into pkg directory.
240 for directory in args.sdk_ext_directories: 259 common_source_prefix = os.path.dirname(os.path.commonprefix(
241 sdk_ext_sources = list_files(directory, dart_filter) 260 args.package_sources))
242 common_prefix = os.path.commonprefix(sdk_ext_sources) 261 for source in args.package_sources:
243 for source in sdk_ext_sources: 262 relative_source = os.path.relpath(source, common_source_prefix)
244 relative_source = os.path.relpath(source, common_prefix) 263 target = os.path.join(target_dir, relative_source)
245 target = os.path.join(sdk_ext_dir, relative_source) 264 copy_or_link(source, target)
246 copy_or_link(source, target) 265
247 for source in args.sdk_ext_files: 266 entrypoint_targets = []
248 common_prefix = os.path.commonprefix(args.sdk_ext_files) 267 for source in args.package_entrypoints:
249 relative_source = os.path.relpath(source, common_prefix) 268 relative_source = os.path.relpath(source, common_source_prefix)
250 target = os.path.join(sdk_ext_dir, relative_source) 269 target = os.path.join(target_dir, relative_source)
251 copy_or_link(source, target) 270 copy_or_link(source, target)
252 271 entrypoint_targets.append(target)
253 lib_mojom_path = os.path.join(lib_path, "mojom") 272
254 273 # Copy sdk-ext sources into pkg directory
255 # Copy generated mojom.dart files. 274 sdk_ext_dir = os.path.join(target_dir, 'sdk_ext')
256 generated_mojom_lib_path = os.path.join(args.gen_directory, "mojom/lib") 275 for directory in args.sdk_ext_directories:
257 for mojom_source_path in args.mojom_sources: 276 sdk_ext_sources = list_files(directory, dart_filter)
258 path = mojom_path(mojom_source_path) 277 common_prefix = os.path.commonprefix(sdk_ext_sources)
259 source_path = '%s.dart' % os.path.join(generated_mojom_lib_path, path) 278 for source in sdk_ext_sources:
260 target_path = '%s.dart' % os.path.join(lib_mojom_path, path) 279 relative_source = os.path.relpath(source, common_prefix)
261 copy(source_path, target_path) 280 target = os.path.join(sdk_ext_dir, relative_source)
262 281 copy_or_link(source, target)
263 # Symlink packages/ 282 for source in args.sdk_ext_files:
264 package_path = os.path.join(args.package_root, args.package_name) 283 common_prefix = os.path.commonprefix(args.sdk_ext_files)
265 link(lib_path, package_path) 284 relative_source = os.path.relpath(source, common_prefix)
266 285 target = os.path.join(sdk_ext_dir, relative_source)
267 # Remove any broken symlinks in target_dir and package root. 286 copy_or_link(source, target)
268 remove_broken_symlinks(target_dir) 287
269 remove_broken_symlinks(args.package_root) 288 lib_mojom_path = os.path.join(lib_path, "mojom")
270 289
271 # Write stamp file. 290 # Copy generated mojom.dart files.
272 with open(args.stamp_file, 'w'): 291 generated_mojom_lib_path = os.path.join(args.gen_directory, "mojom/lib")
273 pass 292 for mojom_source_path in args.mojom_sources:
293 path = mojom_path(mojom_source_path)
294 source_path = '%s.dart' % os.path.join(generated_mojom_lib_path, path)
295 target_path = '%s.dart' % os.path.join(lib_mojom_path, path)
296 copy(source_path, target_path)
297
298 # Symlink packages/
299 package_path = os.path.join(args.package_root, args.package_name)
300 link(lib_path, package_path)
301
302 # Symlink non-dart-pkg dependent packages
zra 2015/07/27 16:27:46 New code to symlink dependent packages not already
303 dep_packages = os.path.join(common_source_prefix, 'packages')
304 if os.path.exists(dep_packages):
305 for package in os.listdir(dep_packages):
306 source = os.path.join(dep_packages, package)
307 target = os.path.join(args.package_root, package)
308 if not os.path.exists(target):
309 link(source, target)
310
311 # Remove any broken symlinks in target_dir and package root.
312 remove_broken_symlinks(target_dir)
313 remove_broken_symlinks(args.package_root)
314
315 # If any entrypoints are defined, invoke the analyzer on them.
316 if entrypoint_targets != []:
zra 2015/07/27 16:27:46 New code to analyze entrypoints.
317 # Make sure we have a Dart SDK.
318 dart_sdk = args.dart_sdk
319 if dart_sdk is None:
320 dart_sdk = os.environ.get('DART_SDK')
321 if dart_sdk is None:
322 print "Pass --dart-sdk, or define the DART_SDK environment variable"
323 return 1
324
325 result = analyze_entrypoints(dart_sdk, args.package_root,
326 entrypoint_targets)
327 if result != 0:
328 return result
329
330 # Write stamp file.
331 with open(args.stamp_file, 'w'):
332 pass
333
334 return 0
274 335
275 if __name__ == '__main__': 336 if __name__ == '__main__':
276 sys.exit(main()) 337 sys.exit(main())
OLDNEW
« mojo/public/dart/rules.gni ('K') | « mojo/public/tools/dart_analyze.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698