merge_from_chromium.py revision 09ead754abd2cfcffea54040b1c9ac98db8af834
182c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles)#!/usr/bin/python 29df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles)# 39df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles)# Copyright (C) 2012 The Android Open Source Project 49df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles)# 59df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles)# Licensed under the Apache License, Version 2.0 (the "License"); 69df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles)# you may not use this file except in compliance with the License. 79df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles)# You may obtain a copy of the License at 89df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles)# 99df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles)# http://www.apache.org/licenses/LICENSE-2.0 109df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles)# 119df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles)# Unless required by applicable law or agreed to in writing, software 129df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles)# distributed under the License is distributed on an "AS IS" BASIS, 139df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles)# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 149df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles)# See the License for the specific language governing permissions and 159df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles)# limitations under the License. 169df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 1782c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles)"""Merge Chromium into the Android tree.""" 189df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 192efbabe43f012ff9c06c78fc19fae49421a4d356Torne (Richard Coles)import contextlib 205d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles)import logging 216a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles)import optparse 226a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles)import os 236a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles)import re 246a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles)import sys 252efbabe43f012ff9c06c78fc19fae49421a4d356Torne (Richard Coles)import urllib2 261c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) 271c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles)import merge_common 286a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 296a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 309df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles)# We need to import this *after* merging from upstream to get the latest 319df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles)# version. Set it to none here to catch uses before it's imported. 329df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles)webview_licenses = None 339df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 349df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 351c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles)AUTOGEN_MESSAGE = 'This commit was generated by merge_from_chromium.py.' 364465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles)SRC_GIT_BRANCH = 'refs/remotes/history/upstream-master' 379df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 389df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 394465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles)def _ReadGitFile(sha1, path, git_url=None, git_branch=None): 404465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) """Reads a file from a (possibly remote) git project at a specific revision. 4182c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 429df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) Args: 439df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) sha1: The SHA1 at which to read. 449df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) path: The relative path of the file to read. 454465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) git_url: The URL of the git server, if reading a remote project. 464465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) git_branch: The branch to fetch, if reading a remote project. 479df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) Returns: 489df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) The contents of the specified file. 499df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) """ 504465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) if git_url: 514465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) # We fetch the branch to a temporary head so that we don't download the same 524465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) # commits multiple times. 534465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'fetch', '-f', git_url, 544465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) git_branch + ':cached_upstream']) 5582c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) return merge_common.GetCommandStdout(['git', 'show', '%s:%s' % (sha1, path)]) 569df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 579df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 584465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles)def _ParseDEPS(sha1): 599df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) """Parses the .DEPS.git file from Chromium and returns its contents. 6082c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 616a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) Args: 629df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) sha1: The SHA1 at which to read. 636a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) Returns: 646a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) A dictionary of the contents of .DEPS.git at the specified revision 656a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) """ 666a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 676a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) class FromImpl(object): 686a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) """Used to implement the From syntax.""" 696a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 706a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) def __init__(self, module_name): 716a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) self.module_name = module_name 726a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 736a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) def __str__(self): 746a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) return 'From("%s")' % self.module_name 756a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 766a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) class _VarImpl(object): 776a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) def __init__(self, custom_vars, local_scope): 786a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) self._custom_vars = custom_vars 796a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) self._local_scope = local_scope 806a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 816a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) def Lookup(self, var_name): 826a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) """Implements the Var syntax.""" 836a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) if var_name in self._custom_vars: 846a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) return self._custom_vars[var_name] 856a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) elif var_name in self._local_scope.get('vars', {}): 866a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) return self._local_scope['vars'][var_name] 876a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) raise Exception('Var is not defined: %s' % var_name) 886a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 896a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) tmp_locals = {} 906a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) var = _VarImpl({}, tmp_locals) 916a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) tmp_globals = {'From': FromImpl, 'Var': var.Lookup, 'deps_os': {}} 924465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) deps_content = _ReadGitFile(sha1, '.DEPS.git') 936a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) exec(deps_content) in tmp_globals, tmp_locals 946a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) return tmp_locals 956a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 966a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 976a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles)def _GetThirdPartyProjectMergeInfo(third_party_projects, deps_vars): 9882c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) """Gets the git URL and SHA1 for each project based on .DEPS.git. 9982c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 1006a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) Args: 1019df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) third_party_projects: The list of projects to consider. 1029df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) deps_vars: The dictionary of dependencies from .DEPS.git. 1036a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) Returns: 1046a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) A dictionary from project to git URL and SHA1 - 'path: (url, sha1)' 10582c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) Raises: 106862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) TemporaryMergeError: if a project to be merged is not found in .DEPS.git. 1076a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) """ 1086a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) deps_fallback_order = [ 1096a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) deps_vars['deps'], 1106a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) deps_vars['deps_os']['unix'], 1116a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) deps_vars['deps_os']['android'], 1126a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) ] 1136a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) result = {} 1146a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) for path in third_party_projects: 1156a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) for deps in deps_fallback_order: 1166a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) url_plus_sha1 = deps.get(os.path.join('src', path)) 1176a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) if url_plus_sha1: 1186a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) break 1196a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) else: 120862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) raise merge_common.TemporaryMergeError( 12182c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 'Could not find .DEPS.git entry for project %s. This probably ' 12282c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 'means that the project list in merge_from_chromium.py needs to be ' 12382c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 'updated.' % path) 1246a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) match = re.match('(.*?)@(.*)', url_plus_sha1) 1256a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) url = match.group(1) 1266a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) sha1 = match.group(2) 1275d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) logging.debug(' Got URL %s and SHA1 %s for project %s', url, sha1, path) 1286a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) result[path] = {'url': url, 'sha1': sha1} 1296a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) return result 1306a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 1316a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 1324465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles)def _MergeProjects(git_branch, svn_revision, root_sha1, unattended): 13382c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) """Merges each required Chromium project into the Android repository. 13482c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 13582c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) .DEPS.git is consulted to determine which revision each project must be merged 13682c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) at. Only a whitelist of required projects are merged. 13782c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 1386a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) Args: 13982c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) git_branch: The branch in the Chromium repository to merge from. 14082c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) svn_revision: The SVN revision in the Chromium repository to merge from. 14182c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) root_sha1: The git hash corresponding to svn_revision. 14214ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) unattended: Run in unattended mode. 14382c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) Raises: 144862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) TemporaryMergeError: If incompatibly licensed code is left after pruning. 1456a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) """ 1466a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) # The logic for this step lives here, in the Android tree, as it makes no 1476a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) # sense for a Chromium tree to know about this merge. 1486a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 14914ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) if unattended: 15014ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) branch_create_flag = '-B' 15114ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) else: 15214ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) branch_create_flag = '-b' 153862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) branch_name = 'merge-from-chromium-%s' % svn_revision 15414ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) 1555d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) logging.debug('Parsing DEPS ...') 1564465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) deps_vars = _ParseDEPS(root_sha1) 1576a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 1581c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_info = _GetThirdPartyProjectMergeInfo(merge_common.THIRD_PARTY_PROJECTS, 1591c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) deps_vars) 1606a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 1616a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) for path in merge_info: 1624465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) # webkit needs special handling as we have a local mirror 1634465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) local_mirrored = path == 'third_party/WebKit' 1646a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) url = merge_info[path]['url'] 1656a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) sha1 = merge_info[path]['sha1'] 1661c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) dest_dir = os.path.join(merge_common.REPOSITORY_ROOT, path) 1674465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) if local_mirrored: 1684465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) remote = 'history' 1694465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) else: 1704465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) remote = 'goog' 1711c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'checkout', 172862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) branch_create_flag, branch_name, 1734465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) '-t', remote + '/master-chromium'], 1744465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) cwd=dest_dir) 1754465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) if not local_mirrored: 1764465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) logging.debug('Fetching project %s at %s ...', path, sha1) 1774465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'fetch', url], cwd=dest_dir) 1781c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) if merge_common.GetCommandStdout(['git', 'rev-list', '-1', 'HEAD..' + sha1], 1791c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) cwd=dest_dir): 1805d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) logging.debug('Merging project %s at %s ...', path, sha1) 1816a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) # Merge conflicts make git merge return 1, so ignore errors 1821c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'merge', '--no-commit', sha1], 1831c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) cwd=dest_dir, ignore_errors=True) 1841c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.CheckNoConflictsAndCommitMerge( 1859df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 'Merge %s from %s at %s\n\n%s' % (path, url, sha1, AUTOGEN_MESSAGE), 18614ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) cwd=dest_dir, unattended=unattended) 1876a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) else: 1885d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) logging.debug('No new commits to merge in project %s', path) 1896a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 1906a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) # Handle root repository separately. 19114ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'checkout', 192862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) branch_create_flag, branch_name, 1934465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) '-t', 'history/master-chromium']) 1945d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) logging.debug('Merging Chromium at %s ...', root_sha1) 1956a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) # Merge conflicts make git merge return 1, so ignore errors 1961c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'merge', '--no-commit', root_sha1], 1971c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) ignore_errors=True) 1981c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.CheckNoConflictsAndCommitMerge( 1994465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) 'Merge Chromium at r%s (%s)\n\n%s' 2004465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) % (svn_revision, root_sha1, AUTOGEN_MESSAGE), unattended=unattended) 2016a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 2025d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) logging.debug('Getting directories to exclude ...') 2039df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 2049df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) # We import this now that we have merged the latest version. 2059df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) # It imports to a global in order that it can be used to generate NOTICE 206c7fa5294b03fbc8ccab655d87faaa6d6d704018eTorne (Richard Coles) # later. We also disable writing bytecode to keep the source tree clean. 2071c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) sys.path.append(os.path.join(merge_common.REPOSITORY_ROOT, 'android_webview', 2081c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) 'tools')) 209c7fa5294b03fbc8ccab655d87faaa6d6d704018eTorne (Richard Coles) sys.dont_write_bytecode = True 2109df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) global webview_licenses 2119df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) import webview_licenses 212cadf645507c329e0f5d7fbb67d9311cfa26ac638Torne (Richard Coles) import known_issues 2139df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 214cadf645507c329e0f5d7fbb67d9311cfa26ac638Torne (Richard Coles) for path, exclude_list in known_issues.KNOWN_INCOMPATIBLE.iteritems(): 2155d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) logging.debug(' %s', '\n '.join(os.path.join(path, x) for x in 2165d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) exclude_list)) 2171c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) dest_dir = os.path.join(merge_common.REPOSITORY_ROOT, path) 2181c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'rm', '-rf', '--ignore-unmatch'] + 2191c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) exclude_list, cwd=dest_dir) 2203c67328c9fd2fd48405af3950e59893bfdf1287bTorne (Richard Coles) if _ModifiedFilesInIndex(dest_dir): 2211c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'commit', '-m', 222cb12295daa313fcefcfff1681c30f3fe935e762eTorne (Richard Coles) 'Exclude unwanted directories'], 2231c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) cwd=dest_dir) 2243c67328c9fd2fd48405af3950e59893bfdf1287bTorne (Richard Coles) 2259df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) directories_left_over = webview_licenses.GetIncompatibleDirectories() 2269df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) if directories_left_over: 227862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) raise merge_common.TemporaryMergeError( 228862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) 'Incompatibly licensed directories remain: ' + 229862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) '\n'.join(directories_left_over)) 2306a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 2316a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 232862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles)def _GenerateMakefiles(svn_revision, unattended): 23382c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) """Run gyp to generate the Android build system makefiles. 2346a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 23582c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) Args: 23682c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) svn_revision: The SVN revision to mention in generated commit messages. 237862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) unattended: Run in unattended mode. 23882c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) """ 2394098e8316ddaa5b20fd8f97438fd063a5468db0eTorne (Richard Coles) logging.debug('Generating makefiles ...') 2404098e8316ddaa5b20fd8f97438fd063a5468db0eTorne (Richard Coles) 2419df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) # TODO(torne): The .tmp files are generated by 2426a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) # third_party/WebKit/Source/WebCore/WebCore.gyp/WebCore.gyp into the source 2436a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) # tree. We should avoid this, or at least use a more specific name to avoid 2446a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) # accidentally removing or adding other files. 2451c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) for path in merge_common.ALL_PROJECTS: 2461c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) dest_dir = os.path.join(merge_common.REPOSITORY_ROOT, path) 2471c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'rm', '--ignore-unmatch', 2485568eda06be15d573395eaba779d62c09f6f96f1Torne (Richard Coles) 'GypAndroid.*.mk', '*.target.*.mk', 2495568eda06be15d573395eaba779d62c09f6f96f1Torne (Richard Coles) '*.host.*.mk', '*.tmp'], cwd=dest_dir) 2501c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) 251862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) try: 252862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) merge_common.GetCommandStdout(['android_webview/tools/gyp_webview']) 2532735b74c930c17d39cb6510c0c2c0a43df1d181aTorne (Richard Coles) except merge_common.MergeError as e: 254862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) if not unattended: 255862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) raise 256862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) else: 257862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) for path in merge_common.ALL_PROJECTS: 258862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) merge_common.GetCommandStdout( 259862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) ['git', 'reset', '--hard'], 260862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) cwd=os.path.join(merge_common.REPOSITORY_ROOT, path)) 2612735b74c930c17d39cb6510c0c2c0a43df1d181aTorne (Richard Coles) raise merge_common.TemporaryMergeError('Makefile generation failed: ' + 26272724a6d44b1f9ebc7e122045a72f3502185844dTorne (Richard Coles) str(e)) 2631c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) 2641c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) for path in merge_common.ALL_PROJECTS: 2651c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) dest_dir = os.path.join(merge_common.REPOSITORY_ROOT, path) 2669df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) # git add doesn't have an --ignore-unmatch so we have to do this instead: 2675568eda06be15d573395eaba779d62c09f6f96f1Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'add', '-f', 'GypAndroid.*.mk'], 2681c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) ignore_errors=True, cwd=dest_dir) 2695568eda06be15d573395eaba779d62c09f6f96f1Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'add', '-f', '*.target.*.mk'], 2701c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) ignore_errors=True, cwd=dest_dir) 2715568eda06be15d573395eaba779d62c09f6f96f1Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'add', '-f', '*.host.*.mk'], 2721c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) ignore_errors=True, cwd=dest_dir) 2731c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'add', '-f', '*.tmp'], 2741c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) ignore_errors=True, cwd=dest_dir) 2759df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) # Only try to commit the makefiles if something has actually changed. 2769df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) if _ModifiedFilesInIndex(dest_dir): 27782c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) merge_common.GetCommandStdout( 27882c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) ['git', 'commit', '-m', 27982c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 'Update makefiles after merge of Chromium at r%s\n\n%s' % 28082c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) (svn_revision, AUTOGEN_MESSAGE)], cwd=dest_dir) 2816a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 2829df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 2831c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles)def _ModifiedFilesInIndex(cwd=merge_common.REPOSITORY_ROOT): 28482c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) """Returns true if git's index contains any changes.""" 2851c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) status = merge_common.GetCommandStdout(['git', 'status', '--porcelain'], 2861c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) cwd=cwd) 28782c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) return re.search(r'^[MADRC]', status, flags=re.MULTILINE) is not None 2886a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 2896a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 2906a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles)def _GenerateNoticeFile(svn_revision): 29182c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) """Generates and commits a NOTICE file containing code licenses. 29282c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 29382c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) This covers all third-party code (from Android's perspective) that lives in 29482c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) the Chromium tree. 29582c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 2966a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) Args: 29782c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) svn_revision: The SVN revision for the main Chromium repository. 2986a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) """ 2995d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) logging.debug('Regenerating NOTICE file ...') 3006a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 3019df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) contents = webview_licenses.GenerateNoticeFile() 3026a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 3031c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) with open(os.path.join(merge_common.REPOSITORY_ROOT, 'NOTICE'), 'w') as f: 3046a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) f.write(contents) 3051c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'add', 'NOTICE']) 3066a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) # Only try to commit the NOTICE update if the file has actually changed. 3076a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) if _ModifiedFilesInIndex(): 3081c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout([ 3096a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 'git', 'commit', '-m', 3106a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 'Update NOTICE file after merge of Chromium at r%s\n\n%s' 3116a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) % (svn_revision, AUTOGEN_MESSAGE)]) 3126a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 3136a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 314e9d946910fc23e839e0ba89df0a59cdcd1aac8ddTorne (Richard Coles)def _GenerateLastChange(svn_revision): 31582c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) """Write a build/util/LASTCHANGE file containing the current revision. 31682c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 31782c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) The revision number is compiled into the binary at build time from this file. 31882c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 319e9d946910fc23e839e0ba89df0a59cdcd1aac8ddTorne (Richard Coles) Args: 32082c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) svn_revision: The SVN revision for the main Chromium repository. 321e9d946910fc23e839e0ba89df0a59cdcd1aac8ddTorne (Richard Coles) """ 3225d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) logging.debug('Updating LASTCHANGE ...') 3231c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) with open(os.path.join(merge_common.REPOSITORY_ROOT, 'build/util/LASTCHANGE'), 3241c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) 'w') as f: 32582c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) f.write('LASTCHANGE=%s\n' % svn_revision) 3261c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'add', '-f', 'build/util/LASTCHANGE']) 327e9d946910fc23e839e0ba89df0a59cdcd1aac8ddTorne (Richard Coles) if _ModifiedFilesInIndex(): 3281c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout([ 329e9d946910fc23e839e0ba89df0a59cdcd1aac8ddTorne (Richard Coles) 'git', 'commit', '-m', 330e9d946910fc23e839e0ba89df0a59cdcd1aac8ddTorne (Richard Coles) 'Update LASTCHANGE file after merge of Chromium at r%s\n\n%s' 331e9d946910fc23e839e0ba89df0a59cdcd1aac8ddTorne (Richard Coles) % (svn_revision, AUTOGEN_MESSAGE)]) 332e9d946910fc23e839e0ba89df0a59cdcd1aac8ddTorne (Richard Coles) 333e9d946910fc23e839e0ba89df0a59cdcd1aac8ddTorne (Richard Coles) 334862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles)def GetLKGR(): 335862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) """Fetch the last known good release from Chromium's dashboard. 336862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) 337862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) Returns: 338862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) The last known good SVN revision. 339862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) """ 340862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) with contextlib.closing( 341862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) urllib2.urlopen('https://chromium-status.appspot.com/lkgr')) as lkgr: 342862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) return int(lkgr.read()) 343862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) 344862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) 345a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liudef GetHEAD(): 346a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu """Fetch the latest HEAD revision from the git mirror of the Chromium svn 347a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu repo. 348a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu 349a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu Returns: 350a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu The latest HEAD SVN revision. 351a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu """ 3524465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) (svn_revision, root_sha1) = _GetSVNRevisionAndSHA1(SRC_GIT_BRANCH, 3534465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) 'HEAD') 354a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu return int(svn_revision) 355a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu 356a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu 3573977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liudef _ParseSvnRevisionFromGitCommitMessage(commit_message): 3583977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu return re.search(r'^git-svn-id: .*@([0-9]+)', commit_message, 3593977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu flags=re.MULTILINE).group(1) 3603977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu 3613977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu 3623977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liudef _GetSVNRevisionFromSha(sha1): 3633977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu commit = merge_common.GetCommandStdout([ 3643977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu 'git', 'show', '--format=%H%n%b', sha1]) 3653977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu return _ParseSvnRevisionFromGitCommitMessage(commit) 3663977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu 3673977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu 3684465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles)def _GetSVNRevisionAndSHA1(git_branch, svn_revision, sha1=None): 3695d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) logging.debug('Getting SVN revision and SHA1 ...') 3703977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu 3713977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu if sha1: 3723977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu return (_GetSVNRevisionFromSha(sha1), sha1) 3733977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu 3749536a5e5660bc0745d1f5f2f6a6468fa53ffa639Bo Liu if svn_revision == 'HEAD': 3759536a5e5660bc0745d1f5f2f6a6468fa53ffa639Bo Liu # Just use the latest commit. 3769536a5e5660bc0745d1f5f2f6a6468fa53ffa639Bo Liu commit = merge_common.GetCommandStdout([ 3779536a5e5660bc0745d1f5f2f6a6468fa53ffa639Bo Liu 'git', 'log', '-n1', '--grep=git-svn-id:', '--format=%H%n%b', 3784465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) git_branch]) 3799536a5e5660bc0745d1f5f2f6a6468fa53ffa639Bo Liu sha1 = commit.split()[0] 3803977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu svn_revision = _ParseSvnRevisionFromGitCommitMessage(commit) 3819536a5e5660bc0745d1f5f2f6a6468fa53ffa639Bo Liu return (svn_revision, sha1) 3829536a5e5660bc0745d1f5f2f6a6468fa53ffa639Bo Liu 3832efbabe43f012ff9c06c78fc19fae49421a4d356Torne (Richard Coles) if svn_revision is None: 3842efbabe43f012ff9c06c78fc19fae49421a4d356Torne (Richard Coles) # Fetch LKGR from upstream. 385862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) svn_revision = GetLKGR() 3862efbabe43f012ff9c06c78fc19fae49421a4d356Torne (Richard Coles) output = merge_common.GetCommandStdout([ 3872efbabe43f012ff9c06c78fc19fae49421a4d356Torne (Richard Coles) 'git', 'log', '--grep=git-svn-id: .*@%s' % svn_revision, 3884465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) '--format=%H', git_branch]) 3892efbabe43f012ff9c06c78fc19fae49421a4d356Torne (Richard Coles) if not output: 390862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) raise merge_common.TemporaryMergeError('Revision %s not found in git repo.' 391862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) % svn_revision) 3922efbabe43f012ff9c06c78fc19fae49421a4d356Torne (Richard Coles) # The log grep will sometimes match reverts/reapplies of commits. We take the 3932efbabe43f012ff9c06c78fc19fae49421a4d356Torne (Richard Coles) # oldest (last) match because the first time it appears in history is 3942efbabe43f012ff9c06c78fc19fae49421a4d356Torne (Richard Coles) # overwhelmingly likely to be the correct commit. 3952efbabe43f012ff9c06c78fc19fae49421a4d356Torne (Richard Coles) sha1 = output.split()[-1] 3966a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) return (svn_revision, sha1) 3976a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 3986a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 3993977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liudef Snapshot(svn_revision, root_sha1, unattended): 40082c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) """Takes a snapshot of the Chromium tree and merges it into Android. 40182c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 40282c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) Android makefiles and a top-level NOTICE file are generated and committed 40382c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) after the merge. 40482c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 4056a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) Args: 40682c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) svn_revision: The SVN revision in the Chromium repository to merge from. 4073977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu root_sha1: The sha1 in the Chromium git mirror to merge from. Only one of 4083977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu svn_revision and root_sha1 should be specified. 40914ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) unattended: Run in unattended mode. 4106a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 41182c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) Returns: 41282c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) True if new commits were merged; False if no new commits were present. 41382c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) """ 414a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu git_branch = SRC_GIT_BRANCH 4154465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) (svn_revision, root_sha1) = _GetSVNRevisionAndSHA1(git_branch, svn_revision, 4164465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) root_sha1) 4171c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) if not merge_common.GetCommandStdout(['git', 'rev-list', '-1', 4181c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) 'HEAD..' + root_sha1]): 4194465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) logging.info('No new commits to merge from %s at r%s (%s)', 4204465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) git_branch, svn_revision, root_sha1) 42182c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) return False 4226a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 4234465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) logging.info('Snapshotting Chromium from %s at r%s (%s)', 4244465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) git_branch, svn_revision, root_sha1) 4256a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 4266a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) # 1. Merge, accounting for excluded directories 4274465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) _MergeProjects(git_branch, svn_revision, root_sha1, unattended) 4286a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 4299df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) # 2. Generate Android NOTICE file 4306a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) _GenerateNoticeFile(svn_revision) 4316a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 432e9d946910fc23e839e0ba89df0a59cdcd1aac8ddTorne (Richard Coles) # 3. Generate LASTCHANGE file 433e9d946910fc23e839e0ba89df0a59cdcd1aac8ddTorne (Richard Coles) _GenerateLastChange(svn_revision) 434e9d946910fc23e839e0ba89df0a59cdcd1aac8ddTorne (Richard Coles) 435e9d946910fc23e839e0ba89df0a59cdcd1aac8ddTorne (Richard Coles) # 4. Generate Android makefiles 436862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) _GenerateMakefiles(svn_revision, unattended) 4379df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 4381896d5d734a45c412f47fe58816665d374617d3bTorne (Richard Coles) return True 4391896d5d734a45c412f47fe58816665d374617d3bTorne (Richard Coles) 4406a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 441862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles)def Push(svn_revision): 442bda7cff5dd92725ba000fe95d9434f81a7af486eTorne (Richard Coles) """Push the finished snapshot to the Android repository.""" 44309ead754abd2cfcffea54040b1c9ac98db8af834Torne (Richard Coles) src = 'merge-from-chromium-%s' % svn_revision 44409ead754abd2cfcffea54040b1c9ac98db8af834Torne (Richard Coles) for branch in ['master-chromium-merge', 'master-chromium']: 44509ead754abd2cfcffea54040b1c9ac98db8af834Torne (Richard Coles) logging.debug('Pushing to server (%s) ...' % branch) 44609ead754abd2cfcffea54040b1c9ac98db8af834Torne (Richard Coles) for path in merge_common.ALL_PROJECTS: 44709ead754abd2cfcffea54040b1c9ac98db8af834Torne (Richard Coles) if path in merge_common.PROJECTS_WITH_FLAT_HISTORY: 44809ead754abd2cfcffea54040b1c9ac98db8af834Torne (Richard Coles) remote = 'history' 44909ead754abd2cfcffea54040b1c9ac98db8af834Torne (Richard Coles) else: 45009ead754abd2cfcffea54040b1c9ac98db8af834Torne (Richard Coles) remote = 'goog' 45109ead754abd2cfcffea54040b1c9ac98db8af834Torne (Richard Coles) logging.debug('Pushing %s', path) 45209ead754abd2cfcffea54040b1c9ac98db8af834Torne (Richard Coles) dest_dir = os.path.join(merge_common.REPOSITORY_ROOT, path) 45309ead754abd2cfcffea54040b1c9ac98db8af834Torne (Richard Coles) GetCommandStdout(['git', 'push', '-f', remote, src + ':' + branch], 45409ead754abd2cfcffea54040b1c9ac98db8af834Torne (Richard Coles) cwd=dest_dir) 455bda7cff5dd92725ba000fe95d9434f81a7af486eTorne (Richard Coles) 456bda7cff5dd92725ba000fe95d9434f81a7af486eTorne (Richard Coles) 4576a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles)def main(): 4586a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) parser = optparse.OptionParser(usage='%prog [options]') 4596a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) parser.epilog = ('Takes a snapshot of the Chromium tree at the specified ' 4606a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 'Chromium SVN revision and merges it into this repository. ' 4616a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 'Paths marked as excluded for license reasons are removed ' 4626a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 'as part of the merge. Also generates Android makefiles and ' 4636a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 'generates a top-level NOTICE file suitable for use in the ' 4646a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 'Android build.') 4656a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) parser.add_option( 4666a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) '', '--svn_revision', 4676a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) default=None, 4686a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) help=('Merge to the specified chromium SVN revision, rather than using ' 4693977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu 'the current LKGR. Can also pass HEAD to merge from tip of tree. ' 4703977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu 'Only one of svn_revision and sha1 should be specified')) 4713977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu parser.add_option( 4723977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu '', '--sha1', 4733977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu default=None, 4743977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu help=('Merge to the specified chromium sha1 revision from ' + SRC_GIT_BRANCH 4753977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu + ' branch, rather than using the current LKGR. Only one of' 4763977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu 'svn_revision and sha1 should be specified.')) 4771896d5d734a45c412f47fe58816665d374617d3bTorne (Richard Coles) parser.add_option( 47814ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) '', '--push', 47914ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) default=False, action='store_true', 4803977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu help=('Push the result of a previous merge to the server. Note ' 4813977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu 'svn_revision must be given.')) 48214ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) parser.add_option( 4839fb672be51066b51a372885377cc0eff78e1a34cTorne (Richard Coles) '', '--get_lkgr', 4849fb672be51066b51a372885377cc0eff78e1a34cTorne (Richard Coles) default=False, action='store_true', 4859fb672be51066b51a372885377cc0eff78e1a34cTorne (Richard Coles) help=('Just print the current LKGR on stdout and exit.')) 4869fb672be51066b51a372885377cc0eff78e1a34cTorne (Richard Coles) parser.add_option( 487a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu '', '--get_head', 488a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu default=False, action='store_true', 489a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu help=('Just print the current HEAD revision on stdout and exit.')) 490a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu parser.add_option( 49114ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) '', '--unattended', 4921896d5d734a45c412f47fe58816665d374617d3bTorne (Richard Coles) default=False, action='store_true', 49314ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) help=('Run in unattended mode.')) 494d2a42d0b062f4c9bb4c3fefc80cde98350b5974eTorne (Richard Coles) parser.add_option( 495d2a42d0b062f4c9bb4c3fefc80cde98350b5974eTorne (Richard Coles) '', '--no_changes_exit', 496d2a42d0b062f4c9bb4c3fefc80cde98350b5974eTorne (Richard Coles) default=0, type='int', 497d2a42d0b062f4c9bb4c3fefc80cde98350b5974eTorne (Richard Coles) help=('Exit code to use if there are no changes to merge, for scripts.')) 4986a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) (options, args) = parser.parse_args() 4996a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) if args: 5006a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) parser.print_help() 5016a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) return 1 5026a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 5036a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) if 'ANDROID_BUILD_TOP' not in os.environ: 5046a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) print >>sys.stderr, 'You need to run the Android envsetup.sh and lunch.' 5056a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) return 1 5066a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 5075d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) logging.basicConfig(format='%(message)s', level=logging.DEBUG, 5085d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) stream=sys.stdout) 5095d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) 5109fb672be51066b51a372885377cc0eff78e1a34cTorne (Richard Coles) if options.get_lkgr: 5119fb672be51066b51a372885377cc0eff78e1a34cTorne (Richard Coles) print GetLKGR() 512a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu elif options.get_head: 513a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu logging.disable(logging.CRITICAL) # Prevent log messages 514a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu print GetHEAD() 5159fb672be51066b51a372885377cc0eff78e1a34cTorne (Richard Coles) elif options.push: 516862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) if options.svn_revision is None: 517862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) print >>sys.stderr, 'You need to pass the SVN revision to push.' 518862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) return 1 519862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) else: 520862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) Push(options.svn_revision) 52114ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) else: 5223977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu if not Snapshot(options.svn_revision, options.sha1, options.unattended): 523d2a42d0b062f4c9bb4c3fefc80cde98350b5974eTorne (Richard Coles) return options.no_changes_exit 52414ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) 5256a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) return 0 5266a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 5276a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles)if __name__ == '__main__': 5286a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) sys.exit(main()) 529