OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 # Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
3 # | 3 # |
4 # Use of this source code is governed by a BSD-style license | 4 # Use of this source code is governed by a BSD-style license |
5 # that can be found in the LICENSE file in the root of the source | 5 # that can be found in the LICENSE file in the root of the source |
6 # tree. An additional intellectual property rights grant can be found | 6 # tree. An additional intellectual property rights grant can be found |
7 # in the file PATENTS. All contributing project authors may | 7 # in the file PATENTS. All contributing project authors may |
8 # be found in the AUTHORS file in the root of the source tree. | 8 # be found in the AUTHORS file in the root of the source tree. |
9 | 9 |
10 """Script to automatically roll dependencies in the WebRTC DEPS file.""" | 10 """Script to automatically roll dependencies in the WebRTC DEPS file.""" |
11 | 11 |
12 import argparse | 12 import argparse |
13 import base64 | 13 import base64 |
14 import collections | 14 import collections |
15 import logging | 15 import logging |
16 import os | 16 import os |
17 import re | 17 import re |
18 import subprocess | 18 import subprocess |
19 import sys | 19 import sys |
20 import urllib | 20 import urllib |
21 | 21 |
22 | 22 |
23 # Skip these dependencies (list without solution name prefix). | 23 # Skip these dependencies (list without solution name prefix). |
24 DONT_AUTOROLL_THESE = [ | 24 DONT_AUTOROLL_THESE = [ |
25 'src/third_party/gflags/src', | 25 'src/third_party/gflags/src', |
26 'src/third_party/winsdk_samples/src', | 26 'src/third_party/winsdk_samples', |
27 ] | 27 ] |
28 | 28 |
29 WEBRTC_URL = 'https://chromium.googlesource.com/external/webrtc' | 29 WEBRTC_URL = 'https://chromium.googlesource.com/external/webrtc' |
30 CHROMIUM_SRC_URL = 'https://chromium.googlesource.com/chromium/src' | 30 CHROMIUM_SRC_URL = 'https://chromium.googlesource.com/chromium/src' |
31 CHROMIUM_COMMIT_TEMPLATE = CHROMIUM_SRC_URL + '/+/%s' | 31 CHROMIUM_COMMIT_TEMPLATE = CHROMIUM_SRC_URL + '/+/%s' |
32 CHROMIUM_LOG_TEMPLATE = CHROMIUM_SRC_URL + '/+log/%s' | 32 CHROMIUM_LOG_TEMPLATE = CHROMIUM_SRC_URL + '/+log/%s' |
33 CHROMIUM_FILE_TEMPLATE = CHROMIUM_SRC_URL + '/+/%s/%s' | 33 CHROMIUM_FILE_TEMPLATE = CHROMIUM_SRC_URL + '/+/%s/%s' |
34 | 34 |
35 COMMIT_POSITION_RE = re.compile('^Cr-Commit-Position: .*#([0-9]+).*$') | 35 COMMIT_POSITION_RE = re.compile('^Cr-Commit-Position: .*#([0-9]+).*$') |
36 CLANG_REVISION_RE = re.compile(r'^CLANG_REVISION = \'(\d+)\'$') | 36 CLANG_REVISION_RE = re.compile(r'^CLANG_REVISION = \'(\d+)\'$') |
37 ROLL_BRANCH_NAME = 'roll_chromium_revision' | 37 ROLL_BRANCH_NAME = 'roll_chromium_revision' |
38 | 38 |
39 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) | 39 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) |
40 CHECKOUT_SRC_DIR = os.path.realpath(os.path.join(SCRIPT_DIR, os.pardir, | 40 CHECKOUT_SRC_DIR = os.path.realpath(os.path.join(SCRIPT_DIR, os.pardir, |
41 os.pardir)) | 41 os.pardir)) |
42 CHECKOUT_ROOT_DIR = os.path.realpath(os.path.join(CHECKOUT_SRC_DIR, os.pardir)) | 42 CHECKOUT_ROOT_DIR = os.path.realpath(os.path.join(CHECKOUT_SRC_DIR, os.pardir)) |
43 CHROMIUM_CHECKOUT_SRC_DIR = os.path.join(CHECKOUT_SRC_DIR, 'chromium', 'src') | |
44 | |
45 sys.path.append(CHECKOUT_SRC_DIR) | |
46 import setup_links | |
47 | 43 |
48 sys.path.append(os.path.join(CHECKOUT_SRC_DIR, 'build')) | 44 sys.path.append(os.path.join(CHECKOUT_SRC_DIR, 'build')) |
49 import find_depot_tools | 45 import find_depot_tools |
50 find_depot_tools.add_depot_tools_to_path() | 46 find_depot_tools.add_depot_tools_to_path() |
51 from gclient import GClientKeywords | 47 from gclient import GClientKeywords |
52 | 48 |
53 CLANG_UPDATE_SCRIPT_URL_PATH = 'tools/clang/scripts/update.py' | 49 CLANG_UPDATE_SCRIPT_URL_PATH = 'tools/clang/scripts/update.py' |
54 CLANG_UPDATE_SCRIPT_LOCAL_PATH = os.path.join('tools', 'clang', 'scripts', | 50 CLANG_UPDATE_SCRIPT_LOCAL_PATH = os.path.join(CHECKOUT_SRC_DIR, 'tools', |
55 'update.py') | 51 'clang', 'scripts', 'update.py') |
56 | 52 |
57 DepsEntry = collections.namedtuple('DepsEntry', 'path url revision') | 53 DepsEntry = collections.namedtuple('DepsEntry', 'path url revision') |
58 ChangedDep = collections.namedtuple('ChangedDep', | 54 ChangedDep = collections.namedtuple('ChangedDep', |
59 'path url current_rev new_rev') | 55 'path url current_rev new_rev') |
60 | 56 |
61 class RollError(Exception): | 57 class RollError(Exception): |
62 pass | 58 pass |
63 | 59 |
64 | 60 |
65 def ParseDepsDict(deps_content): | 61 def ParseDepsDict(deps_content): |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 if not result.has_key(path): | 206 if not result.has_key(path): |
211 url, revision = deps_url.split('@') if deps_url else (None, None) | 207 url, revision = deps_url.split('@') if deps_url else (None, None) |
212 result[path] = DepsEntry(path, url, revision) | 208 result[path] = DepsEntry(path, url, revision) |
213 | 209 |
214 AddDepsEntries(deps_dict['deps']) | 210 AddDepsEntries(deps_dict['deps']) |
215 for deps_os in ['win', 'mac', 'unix', 'android', 'ios', 'unix']: | 211 for deps_os in ['win', 'mac', 'unix', 'android', 'ios', 'unix']: |
216 AddDepsEntries(deps_dict.get('deps_os', {}).get(deps_os, {})) | 212 AddDepsEntries(deps_dict.get('deps_os', {}).get(deps_os, {})) |
217 return result | 213 return result |
218 | 214 |
219 | 215 |
220 def CalculateChangedDeps(webrtc_deps, old_cr_deps, new_cr_deps): | 216 def CalculateChangedDeps(webrtc_deps, new_cr_deps): |
221 """ | 217 """ |
222 Calculate changed deps entries based on: | 218 Calculate changed deps entries based on entries defined in the WebRTC DEPS |
223 1. Entries defined in the WebRTC DEPS file: | 219 file: |
224 - If a shared dependency with the Chromium DEPS file: roll it to the same | 220 - If a shared dependency with the Chromium DEPS file: roll it to the same |
225 revision as Chromium (i.e. entry in the new_cr_deps dict) | 221 revision as Chromium (i.e. entry in the new_cr_deps dict) |
226 - If it's a Chromium sub-directory, roll it to the HEAD revision (notice | 222 - If it's a Chromium sub-directory, roll it to the HEAD revision (notice |
227 this means it may be ahead of the chromium_revision, but generally these | 223 this means it may be ahead of the chromium_revision, but generally these |
228 should be close). | 224 should be close). |
229 - If it's another DEPS entry (not shared with Chromium), roll it to HEAD | 225 - If it's another DEPS entry (not shared with Chromium), roll it to HEAD |
230 unless it's configured to be skipped. | 226 unless it's configured to be skipped. |
231 2. Entries present in the setup_links.py file. If the dir has changed between | |
232 old_cr_deps and new_cr_deps, it is considered changed and updated to the | |
233 revision for the entry in the new_cr_deps dict. | |
234 | 227 |
235 Returns: | 228 Returns: |
236 A list of ChangedDep objects representing the changed deps. | 229 A list of ChangedDep objects representing the changed deps. |
237 """ | 230 """ |
238 return sorted(CalculateChangedDepsProper(webrtc_deps, new_cr_deps) + | |
239 CalculateChangedDepsLegacy(old_cr_deps, new_cr_deps)) | |
240 | |
241 | |
242 def CalculateChangedDepsProper(webrtc_deps, new_cr_deps): | |
243 result = [] | 231 result = [] |
244 webrtc_entries = BuildDepsentryDict(webrtc_deps) | 232 webrtc_entries = BuildDepsentryDict(webrtc_deps) |
245 new_cr_entries = BuildDepsentryDict(new_cr_deps) | 233 new_cr_entries = BuildDepsentryDict(new_cr_deps) |
246 for path, webrtc_deps_entry in webrtc_entries.iteritems(): | 234 for path, webrtc_deps_entry in webrtc_entries.iteritems(): |
247 if path in DONT_AUTOROLL_THESE: | 235 if path in DONT_AUTOROLL_THESE: |
248 continue | 236 continue |
249 cr_deps_entry = new_cr_entries.get(path) | 237 cr_deps_entry = new_cr_entries.get(path) |
250 if cr_deps_entry: | 238 if cr_deps_entry: |
251 # Use the revision from Chromium's DEPS file. | 239 # Use the revision from Chromium's DEPS file. |
252 new_rev = cr_deps_entry.revision | 240 new_rev = cr_deps_entry.revision |
253 assert webrtc_deps_entry.url == cr_deps_entry.url, ( | 241 assert webrtc_deps_entry.url == cr_deps_entry.url, ( |
254 'WebRTC DEPS entry %s has a different URL (%s) than Chromium (%s).' % | 242 'WebRTC DEPS entry %s has a different URL (%s) than Chromium (%s).' % |
255 (path, webrtc_deps_entry.url, cr_deps_entry.url)) | 243 (path, webrtc_deps_entry.url, cr_deps_entry.url)) |
256 else: | 244 else: |
257 # Use the HEAD of the deps repo. | 245 # Use the HEAD of the deps repo. |
258 stdout, _ = _RunCommand(['git', 'ls-remote', webrtc_deps_entry.url, | 246 stdout, _ = _RunCommand(['git', 'ls-remote', webrtc_deps_entry.url, |
259 'HEAD']) | 247 'HEAD']) |
260 new_rev = stdout.strip().split('\t')[0] | 248 new_rev = stdout.strip().split('\t')[0] |
261 | 249 |
262 # Check if an update is necessary. | 250 # Check if an update is necessary. |
263 if webrtc_deps_entry.revision != new_rev: | 251 if webrtc_deps_entry.revision != new_rev: |
264 logging.debug('Roll dependency %s to %s', path, new_rev) | 252 logging.debug('Roll dependency %s to %s', path, new_rev) |
265 result.append(ChangedDep(path, webrtc_deps_entry.url, | 253 result.append(ChangedDep(path, webrtc_deps_entry.url, |
266 webrtc_deps_entry.revision, new_rev)) | 254 webrtc_deps_entry.revision, new_rev)) |
267 return result | 255 return sorted(result) |
268 | |
269 | |
270 def CalculateChangedDepsLegacy(old_cr_deps, new_cr_deps): | |
271 result = [] | |
272 new_cr_entries = BuildDepsentryDict(new_cr_deps) | |
273 old_cr_entries = BuildDepsentryDict(old_cr_deps) | |
274 all_deps_dirs = setup_links.DIRECTORIES | |
275 for deps_dir in all_deps_dirs: | |
276 # All deps have 'src' prepended to the path in the Chromium DEPS file. | |
277 dir_path = 'src/%s' % deps_dir | |
278 | |
279 for entry in GetMatchingDepsEntries(old_cr_entries, dir_path): | |
280 new_matching_entries = GetMatchingDepsEntries(new_cr_entries, entry.path) | |
281 assert len(new_matching_entries) <= 1, ( | |
282 'Should never find more than one entry matching %s in %s, found %d' % | |
283 (entry.path, new_cr_entries, len(new_matching_entries))) | |
284 if not new_matching_entries: | |
285 result.append(ChangedDep(entry.path, entry.url, entry.revision, 'None')) | |
286 elif entry != new_matching_entries[0]: | |
287 result.append(ChangedDep(entry.path, entry.url, entry.revision, | |
288 new_matching_entries[0].revision)) | |
289 return result | |
290 | 256 |
291 | 257 |
292 def CalculateChangedClang(new_cr_rev): | 258 def CalculateChangedClang(new_cr_rev): |
293 def GetClangRev(lines): | 259 def GetClangRev(lines): |
294 for line in lines: | 260 for line in lines: |
295 match = CLANG_REVISION_RE.match(line) | 261 match = CLANG_REVISION_RE.match(line) |
296 if match: | 262 if match: |
297 return match.group(1) | 263 return match.group(1) |
298 raise RollError('Could not parse Clang revision!') | 264 raise RollError('Could not parse Clang revision!') |
299 | 265 |
300 chromium_src_path = os.path.join(CHROMIUM_CHECKOUT_SRC_DIR, | 266 with open(CLANG_UPDATE_SCRIPT_LOCAL_PATH, 'rb') as f: |
301 CLANG_UPDATE_SCRIPT_LOCAL_PATH) | |
302 with open(chromium_src_path, 'rb') as f: | |
303 current_lines = f.readlines() | 267 current_lines = f.readlines() |
304 current_rev = GetClangRev(current_lines) | 268 current_rev = GetClangRev(current_lines) |
305 | 269 |
306 new_clang_update_py = ReadRemoteCrFile(CLANG_UPDATE_SCRIPT_URL_PATH, | 270 new_clang_update_py = ReadRemoteCrFile(CLANG_UPDATE_SCRIPT_URL_PATH, |
307 new_cr_rev).splitlines() | 271 new_cr_rev).splitlines() |
308 new_rev = GetClangRev(new_clang_update_py) | 272 new_rev = GetClangRev(new_clang_update_py) |
309 return ChangedDep(CLANG_UPDATE_SCRIPT_LOCAL_PATH, None, current_rev, new_rev) | 273 return ChangedDep(CLANG_UPDATE_SCRIPT_LOCAL_PATH, None, current_rev, new_rev) |
310 | 274 |
311 | 275 |
312 def GenerateCommitMessage(current_cr_rev, new_cr_rev, current_commit_pos, | 276 def GenerateCommitMessage(current_cr_rev, new_cr_rev, current_commit_pos, |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 | 323 |
360 # Update the chromium_revision variable. | 324 # Update the chromium_revision variable. |
361 with open(deps_filename, 'rb') as deps_file: | 325 with open(deps_filename, 'rb') as deps_file: |
362 deps_content = deps_file.read() | 326 deps_content = deps_file.read() |
363 deps_content = deps_content.replace(old_cr_revision, new_cr_revision) | 327 deps_content = deps_content.replace(old_cr_revision, new_cr_revision) |
364 with open(deps_filename, 'wb') as deps_file: | 328 with open(deps_filename, 'wb') as deps_file: |
365 deps_file.write(deps_content) | 329 deps_file.write(deps_content) |
366 | 330 |
367 # Update each individual DEPS entry. | 331 # Update each individual DEPS entry. |
368 for dep in changed_deps: | 332 for dep in changed_deps: |
| 333 local_dep_dir = os.path.join(CHECKOUT_ROOT_DIR, dep.path) |
| 334 if not os.path.isdir(local_dep_dir): |
| 335 raise RollError( |
| 336 'Cannot find local directory %s. Either run\n' |
| 337 'gclient sync --deps=all\n' |
| 338 'or make sure the .gclient file for your solution contains all ' |
| 339 'platforms in the target_os list, i.e.\n' |
| 340 'target_os = ["android", "unix", "mac", "ios", "win"];\n' |
| 341 'Then run "gclient sync" again.' % local_dep_dir) |
369 _, stderr = _RunCommand( | 342 _, stderr = _RunCommand( |
370 ['roll-dep-svn', '--no-verify-revision', dep.path, dep.new_rev], | 343 ['roll-dep-svn', '--no-verify-revision', dep.path, dep.new_rev], |
371 working_dir=CHECKOUT_SRC_DIR, ignore_exit_code=True) | 344 working_dir=CHECKOUT_SRC_DIR, ignore_exit_code=True) |
372 if stderr: | 345 if stderr: |
373 logging.warning('roll-dep-svn: %s', stderr) | 346 logging.warning('roll-dep-svn: %s', stderr) |
374 | 347 |
375 | 348 |
376 def _IsTreeClean(): | 349 def _IsTreeClean(): |
377 stdout, _ = _RunCommand(['git', 'status', '--porcelain']) | 350 stdout, _ = _RunCommand(['git', 'status', '--porcelain']) |
378 if len(stdout) == 0: | 351 if len(stdout) == 0: |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 logging.info('No revision specified. Using HEAD: %s', head_rev) | 454 logging.info('No revision specified. Using HEAD: %s', head_rev) |
482 new_cr_rev = head_rev | 455 new_cr_rev = head_rev |
483 | 456 |
484 deps_filename = os.path.join(CHECKOUT_SRC_DIR, 'DEPS') | 457 deps_filename = os.path.join(CHECKOUT_SRC_DIR, 'DEPS') |
485 webrtc_deps = ParseLocalDepsFile(deps_filename) | 458 webrtc_deps = ParseLocalDepsFile(deps_filename) |
486 current_cr_rev = webrtc_deps['vars']['chromium_revision'] | 459 current_cr_rev = webrtc_deps['vars']['chromium_revision'] |
487 | 460 |
488 current_commit_pos = ParseCommitPosition(ReadRemoteCrCommit(current_cr_rev)) | 461 current_commit_pos = ParseCommitPosition(ReadRemoteCrCommit(current_cr_rev)) |
489 new_commit_pos = ParseCommitPosition(ReadRemoteCrCommit(new_cr_rev)) | 462 new_commit_pos = ParseCommitPosition(ReadRemoteCrCommit(new_cr_rev)) |
490 | 463 |
491 current_cr_deps = ParseRemoteCrDepsFile(current_cr_rev) | |
492 new_cr_deps = ParseRemoteCrDepsFile(new_cr_rev) | 464 new_cr_deps = ParseRemoteCrDepsFile(new_cr_rev) |
493 | 465 changed_deps = CalculateChangedDeps(webrtc_deps, new_cr_deps) |
494 changed_deps = CalculateChangedDeps(webrtc_deps, current_cr_deps, new_cr_deps) | |
495 clang_change = CalculateChangedClang(new_cr_rev) | 466 clang_change = CalculateChangedClang(new_cr_rev) |
496 commit_msg = GenerateCommitMessage(current_cr_rev, new_cr_rev, | 467 commit_msg = GenerateCommitMessage(current_cr_rev, new_cr_rev, |
497 current_commit_pos, new_commit_pos, | 468 current_commit_pos, new_commit_pos, |
498 changed_deps, clang_change) | 469 changed_deps, clang_change) |
499 logging.debug('Commit message:\n%s', commit_msg) | 470 logging.debug('Commit message:\n%s', commit_msg) |
500 | 471 |
501 _CreateRollBranch(opts.dry_run) | 472 _CreateRollBranch(opts.dry_run) |
502 UpdateDepsFile(deps_filename, current_cr_rev, new_cr_rev, changed_deps) | 473 UpdateDepsFile(deps_filename, current_cr_rev, new_cr_rev, changed_deps) |
503 _LocalCommit(commit_msg, opts.dry_run) | 474 _LocalCommit(commit_msg, opts.dry_run) |
504 _UploadCL(opts.dry_run, opts.rietveld_email) | 475 _UploadCL(opts.dry_run, opts.rietveld_email) |
505 _SendToCQ(opts.dry_run, opts.skip_cq) | 476 _SendToCQ(opts.dry_run, opts.skip_cq) |
506 return 0 | 477 return 0 |
507 | 478 |
508 | 479 |
509 if __name__ == '__main__': | 480 if __name__ == '__main__': |
510 sys.exit(main()) | 481 sys.exit(main()) |
OLD | NEW |