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

Side by Side Diff: tools/dom/scripts/idlsync.py

Issue 2875773003: Roll 50: Updated for push to origin/master. (Closed)
Patch Set: Roll 50: Updated to latest Created 3 years, 7 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/python 1 # Upgrading Dart's SDK for HTML (blink IDLs).
2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 #
3 # for details. All rights reserved. Use of this source code is governed by a 3 # Typically this is done using the Dart integration branch (as it has to be
4 # BSD-style license that can be found in the LICENSE file. 4 # staged to get most things working).
5 #
6 # Enlist in third_party/WebCore:
7 # > cd src/dart/third_party
8 # > rm -rf WebCore (NOTE: Normally detached head using gclient sync)
9 # > git clone https://github.com/dart-lang/webcore.git WebCore
10 #
11 # To update all *.idl, *.py, LICENSE files, and IDLExtendedAttributes.txt:
12 # > cd src/dart
13 # > python tools/dom/scripts/idlsync.py
14 #
15 # Display blink files to delete, copy, update, and collisions to review:
16 # > python tools/dom/scripts/idlsync.py --check
17 #
18 # Bring over all blink files to dart/third_party/WebCore (*.py, *.idl, and
19 # IDLExtendedAttributes.txt):
20 # > python tools/dom/scripts/idlsync.py
21 #
22 # Update the DEPS file SHA for "WebCore_rev" with the committed changes of files
23 # in WebCore e.g., "WebCore_rev": "@NNNNNNNNNNNNNNNNNNNNNNNNN"
24 #
25 # Generate the sdk/*.dart files from the new IDLs and PYTHON IDL parsing code
26 # copied to in dart/third_party/WebCore from src/third_party/WebKit (blink).
27 #
28 # > cd src/dart/tools/dom/script
29 # > ./go.sh
30 #
31 # Finally, commit the files in dart/third_party/WebCore.
5 32
6 import optparse 33 import optparse
7 import os
8 import os.path 34 import os.path
9 import re 35 import re
10 import requests 36 import requests
11 import shutil
12 import subprocess 37 import subprocess
13 import sys 38 import sys
14 import tempfile 39 import time
15 40
16 SCRIPT_PATH = os.path.abspath(os.path.dirname(__file__)) 41 from shutil import copyfile
17 DART_PATH = os.path.abspath(os.path.join(SCRIPT_PATH, '..', '..', '..'))
18 42
19 # Dartium DEPS file from the DEPS file checked into the dart-lang/sdk integratio n 43 # Dartium DEPS file from the DEPS file checked into the dart-lang/sdk integratio n
20 # branch. 44 # branch.
21 DEPS_GIT = ('https://raw.githubusercontent.com/dart-lang/sdk/' 45 DEPS_GIT = ('https://raw.githubusercontent.com/dart-lang/sdk/integration/'
22 'integration/tools/deps/dartium.deps/DEPS') 46 'tools/deps/dartium.deps/DEPS')
47 CHROME_TRUNK = "https://chromium.googlesource.com"
48 WEBKIT_URL_PATTERN = r'"dartium_chromium_commit": "(\S+)",'
49 DEPS_PATTERNS = {
50 'webkit': (CHROME_TRUNK, WEBKIT_URL_PATTERN),
51 }
23 52
24 # Whitelist of files to keep. 53 # Dartium/Chromium remote (GIT repository)
25 WHITELIST = [ 54 GIT_REMOTES_CHROMIUM = 'https://chromium.googlesource.com/dart/dartium/src.git'
26 r'LICENSE(\S+)',
27 r'(\S+)\.idl',
28 r'(\S+)\.json',
29 r'(\S+)\.py',
30 r'(\S+)\.txt',
31 ]
32 55
33 # WebKit / WebCore info. 56 # location of this file
34 CHROME_TRUNK = "https://src.chromium.org" 57 SOURCE_FILE_DIR = 'src/dart/tools/dom/scripts'
35 WEBKIT_URL_PATTERN = r'"dartium_webkit_branch": "(\S+)",'
36 WEBKIT_REV_PATTERN = r'"dartium_webkit_revision": "(\d+)",'
37 WEBCORE_SUBPATH = 'Source/core'
38 MODULES_SUBPATH = 'Source/modules'
39 BINDINGS_SUBPATH = 'Source/bindings'
40 58
41 LOCAL_WEBKIT_IDL_PATH = os.path.join(DART_PATH, 'third_party', 'WebCore') 59 WEBKIT_SOURCE = 'src/third_party/WebKit/Source'
42 LOCAL_WEBKIT_README = """\ 60 WEBCORE_SOURCE = 'src/dart/third_party/WebCore'
43 This directory contains a copy of WebKit/WebCore IDL files.
44 See the attached LICENSE-* files in this directory.
45 61
46 Please do not modify the files here. They are periodically copied 62 # Never automatically git add bindings/IDLExtendedAttributes.txt this file has
47 using the script: $DART_ROOT/sdk/lib/html/scripts/%(script)s 63 # been modified by Dart but is usually changed by WebKit blink too.
64 IDL_EXTENDED_ATTRIBUTES_FILE = 'IDLExtendedAttributes.txt'
48 65
49 The current version corresponds to: 66 # Don't automatically update, delete or add anything in this directory:
50 URL: %(url)s 67 # bindings/dart/scripts
51 Current revision: %(revision)s 68 # The scripts in the above directory is the source for our Dart generators that
52 """ 69 # is driven from the blink IDL parser AST
70 DART_SDK_GENERATOR_SCRIPTS = 'bindings/dart/scripts'
53 71
54 # Chrome info. 72 # sub directories containing IDLs (core and modules) from the base directory
55 CHROME_URL_PATTERN = r'"dartium_chromium_branch": "(\S+)",' 73 # src/third_party/WebKit/Source
56 CHROME_REV_PATTERN = r'"dartium_chromium_revision": "(\d+)",' 74 SUBDIRS = [
57 CHROME_IDL_SUBPATH = 'trunk/src/chrome/common/extensions/api' 75 'bindings',
58 CHROME_COMMENT_EATER_SUBPATH = 'trunk/src/tools/json_comment_eater' 76 'core',
59 CHROME_COMPILER_SUBPATH = 'trunk/src/tools/json_schema_compiler' 77 'modules',
60 CHROME_IDL_PARSER_SUBPATH = 'trunk/src/ppapi/generators' 78 ]
61 CHROME_PLY_SUBPATH = 'trunk/src/third_party/ply' 79 IDL_EXT = '.idl'
62 LOCAL_CHROME_IDL_PATH = os.path.join(DART_PATH, 'third_party', 'chrome', 'idl') 80 PY_EXT = '.py'
63 LOCAL_CHROME_COMMENT_EATER_PATH = os.path.join( 81 LICENSE_FILE_PREFIX = 'LICENSE' # e.g., LICENSE-APPLE, etc.
64 DART_PATH, 'third_party', 'chrome', 'tools', 'json_comment_eater')
65 LOCAL_CHROME_COMPILER_PATH = os.path.join(DART_PATH, 'third_party', 'chrome',
66 'tools', 'json_schema_compiler')
67 LOCAL_CHROME_IDL_PARSER_PATH = os.path.join(DART_PATH, 'third_party', 'chrome',
68 'ppapi', 'generators')
69 LOCAL_CHROME_PLY_PATH = os.path.join(DART_PATH, 'third_party', 'chrome',
70 'third_party', 'ply')
71 LOCAL_CHROME_README = """\
72 This directory contains a copy of Chromium IDL and generation scripts
73 used to generate Dart APIs for Chrome Apps.
74 82
75 The original files are from: 83 # Look in any file in WebCore we copy from WebKit if this comment is in the file
76 URL: %(url)s 84 # then flag this as a special .py or .idl file that needs to be looked at.
77 Current revision: %(revision)s 85 DART_CHANGES = ' FIXMEDART: '
78 86
79 Please see the corresponding LICENSE file at 87 # application options passed in.
80 %(url)s/trunk/src/LICENSE. 88 options = None
81 """
82 DEPTH_FILES = 'files'
83 DEPTH_INFINITY = 'infinity'
84 89
85 # Regular expressions corresponding to URL/revision patters in the 90 warning_messages = []
86 # DEPS file.
87 DEPS_PATTERNS = {
88 'webkit': (CHROME_TRUNK, WEBKIT_URL_PATTERN, WEBKIT_REV_PATTERN),
89 # 'chrome': (CHROME_TRUNK, CHROME_URL_PATTERN, CHROME_REV_PATTERN),
90 }
91 91
92 # List of components to update. 92 # Is --check passed in.
93 UPDATE_LIST = [ 93 def isChecked():
94 # (component, remote subpath, local path, local readme file, depth) 94 global options
95 return options['check'] is not None
95 96
96 # WebKit IDL. 97 # Is --verbose passed in.
97 ('webkit', WEBCORE_SUBPATH, os.path.join(LOCAL_WEBKIT_IDL_PATH, 'core'), 98 def isVerbose():
98 LOCAL_WEBKIT_README, DEPTH_INFINITY), 99 global options
99 ('webkit', MODULES_SUBPATH, os.path.join(LOCAL_WEBKIT_IDL_PATH, 'modules'), 100 return options['verbose'] is not None
100 LOCAL_WEBKIT_README, DEPTH_INFINITY),
101 ('webkit', BINDINGS_SUBPATH, os.path.join(LOCAL_WEBKIT_IDL_PATH, 'bindings') ,
102 LOCAL_WEBKIT_README, DEPTH_INFINITY),
103
104 # Chrome IDL.
105 ('chrome', CHROME_IDL_SUBPATH, LOCAL_CHROME_IDL_PATH, LOCAL_CHROME_README,
106 DEPTH_INFINITY),
107 # Chrome PPAPI generators. Contains idl_parser.py which is used by the
108 # Chrome IDL compiler.
109 ('chrome', CHROME_IDL_PARSER_SUBPATH, LOCAL_CHROME_IDL_PARSER_PATH,
110 LOCAL_CHROME_README, DEPTH_FILES),
111 # ply files.
112 ('chrome', CHROME_PLY_SUBPATH, LOCAL_CHROME_PLY_PATH, LOCAL_CHROME_README,
113 DEPTH_INFINITY),
114 # Path for json_comment_eater, which is needed by the Chrome IDL compiler.
115 ('chrome', CHROME_COMMENT_EATER_SUBPATH, LOCAL_CHROME_COMMENT_EATER_PATH,
116 LOCAL_CHROME_README, DEPTH_FILES),
117 # Chrome IDL compiler files.
118 ('chrome', CHROME_COMPILER_SUBPATH, LOCAL_CHROME_COMPILER_PATH,
119 LOCAL_CHROME_README, DEPTH_INFINITY),
120 ]
121
122 101
123 def RunCommand(cmd, valid_exits=[0]): 102 def RunCommand(cmd, valid_exits=[0]):
124 """Executes a shell command and return its stdout.""" 103 """Executes a shell command and return its stdout."""
125 print ' '.join(cmd) 104 if isVerbose():
105 print ' '.join(cmd)
126 pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 106 pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
127 output = pipe.communicate() 107 output = pipe.communicate()
128 if pipe.returncode in valid_exits: 108 if pipe.returncode in valid_exits:
129 return output[0] 109 return output[0]
130 else: 110 else:
131 print output[1] 111 print output[1]
132 print 'FAILED. RET_CODE=%d' % pipe.returncode 112 print 'FAILED. RET_CODE=%d' % pipe.returncode
133 sys.exit(pipe.returncode) 113 sys.exit(pipe.returncode)
134 114
115 # returns True if // FIXMEDART: is in the file.
116 def anyDartFixMe(filepath):
117 if os.path.exists(filepath):
118 data = open(filepath, 'r').read()
119 return data.find(DART_CHANGES) != -1
120 else:
121 return False
122
123 # Give a base_dir compute the trailing directory after base_dir
124 # returns the subpath from base_dir for the path passed in.
125 def subpath(path, base_dir):
126 dir_portion = ''
127 head = path
128 while True:
129 head, tail = os.path.split(head)
130 dir_portion = os.path.join(tail, dir_portion)
131 if head == base_dir or tail == '':
132 break;
133 return dir_portion
134
135 # Copy any file in source_dir (WebKit) to destination_dir (dart/third_party/WebC ore)
136 # source_dir is the src/third_party/WebKit/Source location (blink)
137 # destination_dir is the src/dart/third_party/WebCore location
138 # returns idls_copied, py_copied, other_copied
139 def copy_files(source_dir, destination_dir):
140 original_cwd = os.getcwd()
141 os.chdir(destination_dir)
142
143 idls = 0 # *.idl files copied
144 pys = 0 # *.py files copied
145 others = 0 # all other files copied
146
147 for (root, _, files) in os.walk(source_dir, topdown=False):
148 dir_portion = subpath(root, source_dir)
149 for f in files:
150 # Never automatically add any Dart generator scripts (these are the origin al
151 # sources in WebCore) from WebKit to WebCore.
152 if dir_portion != DART_SDK_GENERATOR_SCRIPTS:
153 if (f.endswith(IDL_EXT) or
154 f == IDL_EXTENDED_ATTRIBUTES_FILE or
155 f.endswith(PY_EXT) or
156 f.startswith(LICENSE_FILE_PREFIX)):
157 if f.endswith(IDL_EXT):
158 idls += 1
159 elif f.endswith(PY_EXT):
160 pys += 1
161 else:
162 others += 1
163 src_file = os.path.join(root, f)
164 dst_root = root.replace(WEBKIT_SOURCE, WEBCORE_SOURCE)
165 dst_file = os.path.join(dst_root, f)
166
167 destination = os.path.dirname(dst_file)
168 if not os.path.exists(destination):
169 os.makedirs(destination)
170
171 has_Dart_fix_me = anyDartFixMe(dst_file)
172
173 if not isChecked():
174 copyfile(src_file, dst_file)
175 if isVerbose():
176 print('...copying %s' % os.path.split(dst_file)[1])
177 if f == IDL_EXTENDED_ATTRIBUTES_FILE:
178 warning_messages.append(dst_file)
179 else:
180 if has_Dart_fix_me:
181 warning_messages.append(dst_file)
182 if not (isChecked() or has_Dart_fix_me):
183 # git add the file
184 RunCommand(['git', 'add', dst_file])
185
186 os.chdir(original_cwd)
187
188 return [idls, pys, others]
189
190 # Remove any file in webcore_dir that no longer exist in the webkit_dir
191 # webcore_dir src/dart/third_party/WebCore location
192 # webkit_dir src/third_party/WebKit/Source location (blink)
193 # only check if the subdir off from webcore_dir
194 # return list of files deleted
195 def remove_obsolete_webcore_files(webcore_dir, webkit_dir, subdir):
196 files_to_delete = []
197
198 original_cwd = os.getcwd()
199 os.chdir(webcore_dir)
200
201 for (root, _, files) in os.walk(os.path.join(webcore_dir, subdir), topdown=Fal se):
202 dir_portion = subpath(root, webcore_dir)
203 for f in files:
204 # Never automatically deleted any Dart generator scripts (these are the
205 # original sources in WebCore).
206 if dir_portion != DART_SDK_GENERATOR_SCRIPTS:
207 check_file = os.path.join(dir_portion, f)
208 check_file_full_path = os.path.join(webkit_dir, check_file)
209 if not os.path.exists(check_file_full_path):
210 if not isChecked():
211 # Remove the file using git
212 RunCommand(['git', 'rm', check_file])
213 files_to_delete.append(check_file)
214
215 os.chdir(original_cwd)
216
217 return files_to_delete
218
219 def ParseOptions():
220 parser = optparse.OptionParser()
221 parser.add_option('--verbose', '-v', dest='verbose', action='store_false',
222 help='Dump all information', default=None)
223 parser.add_option('--check', '-c', dest='check', action='store_false',
224 help='Display results without adding, updating or deleting a ny files', default=None)
225 args, _ = parser.parse_args()
226
227 argOptions = {}
228 argOptions['verbose'] = args.verbose
229 argOptions['check'] = args.check
230 return argOptions
231
232 # Fetch the DEPS file in src/dart/tools/deps/dartium.deps/DEPS from the GIT repr o.
135 def GetDepsFromGit(): 233 def GetDepsFromGit():
136 req = requests.get(DEPS_GIT) 234 req = requests.get(DEPS_GIT)
137 return req.text 235 return req.text
138 236
139 def GetSvnRevision(deps, component): 237 def ValidateGitRemotes():
140 """Returns a tuple with the (dartium webkit repo, latest revision).""" 238 #origin https://chromium.googlesource.com/dart/dartium/src.git (fetch)
141 url_base, url_pattern, rev_pattern = DEPS_PATTERNS[component] 239 remotes_list = RunCommand(['git', 'remote', '--verbose']).split()
240 if (len(remotes_list) > 2 and
241 remotes_list[0] == 'origin' and remotes_list[1] == GIT_REMOTES_CHROMIUM):
242 return True
243
244 print 'ERROR: Unable to find dart/dartium/src repository %s' % GIT_REMOTES_CHR OMIUM
245 return False
246
247 def getCurrentDartiumSHA():
248 cwd = os.getcwd()
249 if cwd.endswith('dart'):
250 # In src/dart
251 src_dir, _ = os.path.split(cwd)
252 elif cwd.endswith('src'):
253 src_dir = cwd
254 else:
255 src_dir = os.path.join(cwd, 'src')
256 os.chdir(src_dir)
257
258 if ValidateGitRemotes():
259 dartium_sha = RunCommand(['git', 'log', '--format=format:%H', '-1'])
260 else:
261 dartium_sha = -1
262
263 os.chdir(cwd)
264 return dartium_sha
265
266 # Returns the SHA of the Dartium/Chromiun in the DEPS file.
267 def GetDEPSDartiumGitRevision(deps, component):
268 """Returns a tuple with the (dartium chromium repo, latest revision)."""
269 url_base, url_pattern = DEPS_PATTERNS[component]
142 url = url_base + re.search(url_pattern, deps).group(1) 270 url = url_base + re.search(url_pattern, deps).group(1)
143 revision = re.search(rev_pattern, deps).group(1) 271 # Get the SHA for the Chromium/WebKit changes for Dartium.
144 return (url, revision) 272 revision = url[len(url_base):]
145 273 return revision
146
147 def RefreshFiles(url, revision, remote_path, local_path, depth):
148 """Refreshes refreshes files in the local_path to specific url /
149 revision / remote_path, exporting to depth"""
150 cwd = os.getcwd()
151 try:
152 if os.path.exists(local_path):
153 shutil.rmtree(local_path)
154 head, tail = os.path.split(local_path)
155 if not os.path.exists(head):
156 os.makedirs(head)
157 os.chdir(head)
158 RunCommand(['svn', 'export', '--depth', depth, '-r', revision,
159 url + '/' + remote_path, tail])
160 finally:
161 os.chdir(cwd)
162
163
164 def PruneExtraFiles(local_path):
165 """Removes all files that do not match the whitelist."""
166 pattern = re.compile(reduce(lambda x,y: '%s|%s' % (x,y),
167 map(lambda z: '(%s)' % z, WHITELIST)))
168 for (root, dirs, files) in os.walk(local_path, topdown=False):
169 for f in files:
170 if not pattern.match(f):
171 os.remove(os.path.join(root, f))
172 for d in dirs:
173 dirpath = os.path.join(root, d)
174 if not os.listdir(dirpath):
175 shutil.rmtree(dirpath)
176
177
178 def GenerateReadme(local_path, template, url, revision):
179 readme = template % {
180 'script': os.path.basename(__file__),
181 'url': url,
182 'revision': revision }
183
184 readme_path = os.path.join(local_path, 'README')
185 out = open(readme_path, 'w')
186 out.write(readme)
187 out.close()
188
189 ZIP_ARCHIVE = 'version-control-dirs.zip'
190
191 def SaveVersionControlDir(local_path):
192 if os.path.exists(local_path):
193 RunCommand([
194 'sh', '-c',
195 'find %s -name .svn -or -name .git | zip -r %s -@' % (
196 os.path.relpath(local_path), ZIP_ARCHIVE)
197 ], [0, 12]) # It is ok if zip has nothing to do (exit code 12).
198
199 def RestoreVersionControlDir(local_path):
200 archive_path = os.path.join(local_path, ZIP_ARCHIVE)
201 if os.path.exists(archive_path):
202 RunCommand(['unzip', ZIP_ARCHIVE, '-d', '.'])
203 RunCommand(['rm', ZIP_ARCHIVE])
204
205 def ParseOptions():
206 parser = optparse.OptionParser()
207 parser.add_option('--webkit-revision', '-w', dest='webkit_revision',
208 help='WebKit IDL revision to install', default=None)
209 parser.add_option('--chrome-revision', '-c', dest='chrome_revision',
210 help='Chrome IDL revision to install', default=None)
211 args, _ = parser.parse_args()
212 update = {}
213 update['webkit'] = args.webkit_revision
214 return update
215
216 274
217 def main(): 275 def main():
218 update = ParseOptions() 276 global options
277 options = ParseOptions()
278
279 current_dir = os.path.dirname(os.path.abspath(__file__))
280 if not current_dir.endswith(SOURCE_FILE_DIR):
281 print 'ERROR: idlsync.py not run in proper directory (%s)\n', current_dir
282
283 base_directory = current_dir[:current_dir.rfind(SOURCE_FILE_DIR)]
284
285 # Validate that the DEPS SHA matches the SHA of the chromium/dartium branch.
219 deps = GetDepsFromGit() 286 deps = GetDepsFromGit()
220 for (component, remote_path, local_path, readme, depth) in UPDATE_LIST: 287 revision = GetDEPSDartiumGitRevision(deps, 'webkit')
221 if component in update.keys(): 288 dartium_sha = getCurrentDartiumSHA()
222 revision = update[component] 289 if not(revision == dartium_sha):
223 url, latest = GetSvnRevision(deps, component) 290 print "ERROR: Chromium/Dartium SHA in DEPS doesn't match the GIT branch."
224 if revision is None: 291 return
225 revision = latest 292
226 SaveVersionControlDir(local_path); 293 start_time = time.time()
227 RefreshFiles(url, revision, remote_path, local_path, depth) 294 for subdir in SUBDIRS:
228 PruneExtraFiles(local_path) 295 webkit_dir = os.path.join(base_directory, WEBKIT_SOURCE)
229 GenerateReadme(local_path, readme, url, revision) 296 webcore_dir = os.path.join(base_directory, WEBCORE_SOURCE)
230 RestoreVersionControlDir(local_path); 297
298 idls_deleted = remove_obsolete_webcore_files(webcore_dir, webkit_dir, subdir )
299 print "%s files removed in WebCore %s" % (idls_deleted.__len__(), subdir)
300 if isVerbose():
301 for delete_file in idls_deleted:
302 print " %s" % delete_file
303
304 idls_copied, py_copied, other_copied = copy_files(os.path.join(webkit_dir, s ubdir), webcore_dir)
305 print "Copied %s IDLs to %s" % (idls_copied, subdir)
306 print "Copied %s PYs to %s" % (py_copied, subdir)
307 print "Copied %s other to %s\n" % (other_copied, subdir)
308
309 end_time = time.time()
310
311 print 'WARNING: File(s) contain FIXMEDART and are NOT "git add " please review :'
312 for warning in warning_messages:
313 print ' %s' % warning
314
315 print '\nDone idlsync completed in %s seconds' % round(end_time - start_time, 2)
231 316
232 if __name__ == '__main__': 317 if __name__ == '__main__':
233 main() 318 sys.exit(main())
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698