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) 195d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles)import logging 206a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles)import optparse 216a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles)import os 226a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles)import re 236a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles)import sys 241c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) 251c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles)import merge_common 266a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 276a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 289df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles)# We need to import this *after* merging from upstream to get the latest 299df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles)# version. Set it to none here to catch uses before it's imported. 309df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles)webview_licenses = None 319df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 329df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 331c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles)AUTOGEN_MESSAGE = 'This commit was generated by merge_from_chromium.py.' 344465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles)SRC_GIT_BRANCH = 'refs/remotes/history/upstream-master' 3570e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci 369df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 374465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles)def _ReadGitFile(sha1, path, git_url=None, git_branch=None): 384465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) """Reads a file from a (possibly remote) git project at a specific revision. 3982c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 409df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) Args: 419df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) sha1: The SHA1 at which to read. 429df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) path: The relative path of the file to read. 434465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) git_url: The URL of the git server, if reading a remote project. 444465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) git_branch: The branch to fetch, if reading a remote project. 459df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) Returns: 469df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) The contents of the specified file. 479df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) """ 484465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) if git_url: 49f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'fetch', '-f', git_url, git_branch]) 5082c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) return merge_common.GetCommandStdout(['git', 'show', '%s:%s' % (sha1, path)]) 519df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 529df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 53f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles)def _ParseDEPS(deps_content): 54753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci """Parses the DEPS file from Chromium and returns its contents. 5582c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 566a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) Args: 57753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci deps_content: The contents of the DEPS file as text. 586a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) Returns: 59753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci A dictionary of the contents of DEPS at the specified revision 606a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) """ 616a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 626a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) class FromImpl(object): 636a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) """Used to implement the From syntax.""" 646a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 656a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) def __init__(self, module_name): 666a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) self.module_name = module_name 676a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 686a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) def __str__(self): 696a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) return 'From("%s")' % self.module_name 706a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 716a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) class _VarImpl(object): 7270e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci 736a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) def __init__(self, custom_vars, local_scope): 746a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) self._custom_vars = custom_vars 756a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) self._local_scope = local_scope 766a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 776a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) def Lookup(self, var_name): 786a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) """Implements the Var syntax.""" 796a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) if var_name in self._custom_vars: 806a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) return self._custom_vars[var_name] 816a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) elif var_name in self._local_scope.get('vars', {}): 826a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) return self._local_scope['vars'][var_name] 836a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) raise Exception('Var is not defined: %s' % var_name) 846a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 856a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) tmp_locals = {} 866a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) var = _VarImpl({}, tmp_locals) 876a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) tmp_globals = {'From': FromImpl, 'Var': var.Lookup, 'deps_os': {}} 8870e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci exec(deps_content) in tmp_globals, tmp_locals # pylint: disable=W0122 896a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) return tmp_locals 906a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 916a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 92f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles)def _GetProjectMergeInfo(projects, deps_vars): 93753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci """Gets the git URL and SHA1 for each project based on DEPS. 9482c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 956a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) Args: 96f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) projects: The list of projects to consider. 97753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci deps_vars: The dictionary of dependencies from DEPS. 986a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) Returns: 996a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) A dictionary from project to git URL and SHA1 - 'path: (url, sha1)' 10082c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) Raises: 101753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci TemporaryMergeError: if a project to be merged is not found in DEPS. 1026a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) """ 1036a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) deps_fallback_order = [ 1046a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) deps_vars['deps'], 1056a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) deps_vars['deps_os']['unix'], 1066a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) deps_vars['deps_os']['android'], 1076a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) ] 1086a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) result = {} 109f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) for path in projects: 1106a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) for deps in deps_fallback_order: 11170e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci if path: 112f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) upstream_path = os.path.join('src', path) 113f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) else: 114f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) upstream_path = 'src' 115f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) url_plus_sha1 = deps.get(upstream_path) 1166a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) if url_plus_sha1: 1176a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) break 1186a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) else: 119862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) raise merge_common.TemporaryMergeError( 120753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci 'Could not find DEPS entry for project %s. This probably ' 12182c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 'means that the project list in merge_from_chromium.py needs to be ' 12282c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 'updated.' % path) 1236a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) match = re.match('(.*?)@(.*)', url_plus_sha1) 1246a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) url = match.group(1) 1256a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) sha1 = match.group(2) 1265d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) logging.debug(' Got URL %s and SHA1 %s for project %s', url, sha1, path) 1276a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) result[path] = {'url': url, 'sha1': sha1} 1286a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) return result 1296a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 1306a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 131f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles)def _MergeProjects(version, root_sha1, target, unattended, buildspec_url): 13282c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) """Merges each required Chromium project into the Android repository. 13382c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 134753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci DEPS is consulted to determine which revision each project must be merged 13582c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) at. Only a whitelist of required projects are merged. 13682c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 1376a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) Args: 138f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) version: The version to mention in generated commit messages. 139f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) root_sha1: The git hash to merge in the root repository. 140f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) target: The target branch to merge to. 14114ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) unattended: Run in unattended mode. 142f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) buildspec_url: URL for buildspec repository, when merging a branch. 143f2e9853ae82a5b792ddf1af7c7d8924e9cb8c9b4Primiano Tucci Returns: 144f2e9853ae82a5b792ddf1af7c7d8924e9cb8c9b4Primiano Tucci The abbrev sha1 merged. It will be either |root_sha1| itself (when merging 145f2e9853ae82a5b792ddf1af7c7d8924e9cb8c9b4Primiano Tucci chromium trunk) or the upstream sha1 of the release. 14682c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) Raises: 147862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) TemporaryMergeError: If incompatibly licensed code is left after pruning. 1486a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) """ 1496a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) # The logic for this step lives here, in the Android tree, as it makes no 1506a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) # sense for a Chromium tree to know about this merge. 1516a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 15214ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) if unattended: 15314ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) branch_create_flag = '-B' 15414ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) else: 15514ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) branch_create_flag = '-b' 156f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) branch_name = 'merge-from-chromium-%s' % version 15714ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) 1585d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) logging.debug('Parsing DEPS ...') 159f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) if root_sha1: 160753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci deps_content = _ReadGitFile(root_sha1, 'DEPS') 161f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) else: 16270e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci # TODO(primiano): At some point the release branches will use DEPS as well, 16370e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci # instead of .DEPS.git. Rename below when that day will come. 164462a80eeb54228445a3601b6aef6a3484cbf2615Bo Liu deps_content = _ReadGitFile('FETCH_HEAD', 165462a80eeb54228445a3601b6aef6a3484cbf2615Bo Liu 'releases/' + version + '/.DEPS.git', 166462a80eeb54228445a3601b6aef6a3484cbf2615Bo Liu buildspec_url, 167462a80eeb54228445a3601b6aef6a3484cbf2615Bo Liu 'master') 1686a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 169f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) deps_vars = _ParseDEPS(deps_content) 170f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) 171f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) merge_info = _GetProjectMergeInfo(merge_common.THIRD_PARTY_PROJECTS, 172f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) deps_vars) 1736a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 1746a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) for path in merge_info: 1754465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) # webkit needs special handling as we have a local mirror 1764465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) local_mirrored = path == 'third_party/WebKit' 1776a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) url = merge_info[path]['url'] 1786a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) sha1 = merge_info[path]['sha1'] 1791c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) dest_dir = os.path.join(merge_common.REPOSITORY_ROOT, path) 1804465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) if local_mirrored: 1814465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) remote = 'history' 1824465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) else: 1834465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) remote = 'goog' 1841c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'checkout', 185862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) branch_create_flag, branch_name, 186f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) '-t', remote + '/' + target], 1874465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) cwd=dest_dir) 188f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) if not local_mirrored or not root_sha1: 1894465da421aa5ee3d2f6a016b961c301040f0fa23Torne (Richard Coles) logging.debug('Fetching project %s at %s ...', path, sha1) 1903cc50c8a8aa48850211f6724bba1d788c9f08180Torne (Richard Coles) fetch_args = ['git', 'fetch', url, sha1] 191816f8b55f5a0143dd4106d12c54915c3cf05625dTorne (Richard Coles) merge_common.GetCommandStdout(fetch_args, cwd=dest_dir) 1921c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) if merge_common.GetCommandStdout(['git', 'rev-list', '-1', 'HEAD..' + sha1], 1931c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) cwd=dest_dir): 1945d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) logging.debug('Merging project %s at %s ...', path, sha1) 1956a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) # Merge conflicts make git merge return 1, so ignore errors 1961c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'merge', '--no-commit', sha1], 1971c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) cwd=dest_dir, ignore_errors=True) 1981c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.CheckNoConflictsAndCommitMerge( 1999df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 'Merge %s from %s at %s\n\n%s' % (path, url, sha1, AUTOGEN_MESSAGE), 20014ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) cwd=dest_dir, unattended=unattended) 2016a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) else: 2025d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) logging.debug('No new commits to merge in project %s', path) 2036a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 2046a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) # Handle root repository separately. 20514ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'checkout', 206862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) branch_create_flag, branch_name, 207f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) '-t', 'history/' + target]) 208f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) if not root_sha1: 209f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) merge_info = _GetProjectMergeInfo([''], deps_vars) 210f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) url = merge_info['']['url'] 211f2e9853ae82a5b792ddf1af7c7d8924e9cb8c9b4Primiano Tucci merged_sha1 = merge_info['']['sha1'] 212f2e9853ae82a5b792ddf1af7c7d8924e9cb8c9b4Primiano Tucci merge_common.GetCommandStdout(['git', 'fetch', url, merged_sha1]) 213f2e9853ae82a5b792ddf1af7c7d8924e9cb8c9b4Primiano Tucci merged_sha1 = merge_common.Abbrev(merged_sha1) 214f2e9853ae82a5b792ddf1af7c7d8924e9cb8c9b4Primiano Tucci merge_msg_version = '%s (%s)' % (version, merged_sha1) 215753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci else: 216753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci merge_msg_version = root_sha1 217f2e9853ae82a5b792ddf1af7c7d8924e9cb8c9b4Primiano Tucci merged_sha1 = root_sha1 218753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci 219f2e9853ae82a5b792ddf1af7c7d8924e9cb8c9b4Primiano Tucci logging.debug('Merging Chromium at %s ...', merged_sha1) 2206a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) # Merge conflicts make git merge return 1, so ignore errors 221f2e9853ae82a5b792ddf1af7c7d8924e9cb8c9b4Primiano Tucci merge_common.GetCommandStdout(['git', 'merge', '--no-commit', merged_sha1], 2221c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) ignore_errors=True) 2231c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.CheckNoConflictsAndCommitMerge( 224753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci 'Merge Chromium at %s\n\n%s' 225753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci % (merge_msg_version, AUTOGEN_MESSAGE), unattended=unattended) 2266a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 2275d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) logging.debug('Getting directories to exclude ...') 2289df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 2299df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) # We import this now that we have merged the latest version. 2309df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) # It imports to a global in order that it can be used to generate NOTICE 231c7fa5294b03fbc8ccab655d87faaa6d6d704018eTorne (Richard Coles) # later. We also disable writing bytecode to keep the source tree clean. 2321c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) sys.path.append(os.path.join(merge_common.REPOSITORY_ROOT, 'android_webview', 2331c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) 'tools')) 234c7fa5294b03fbc8ccab655d87faaa6d6d704018eTorne (Richard Coles) sys.dont_write_bytecode = True 23570e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci global webview_licenses # pylint: disable=W0602 23670e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci import webview_licenses # pylint: disable=W0621,W0612,C6204 23770e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci import known_issues # pylint: disable=C6204 2389df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 239cadf645507c329e0f5d7fbb67d9311cfa26ac638Torne (Richard Coles) for path, exclude_list in known_issues.KNOWN_INCOMPATIBLE.iteritems(): 2405d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) logging.debug(' %s', '\n '.join(os.path.join(path, x) for x in 2415d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) exclude_list)) 2421c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) dest_dir = os.path.join(merge_common.REPOSITORY_ROOT, path) 2431c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'rm', '-rf', '--ignore-unmatch'] + 2441c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) exclude_list, cwd=dest_dir) 2453c67328c9fd2fd48405af3950e59893bfdf1287bTorne (Richard Coles) if _ModifiedFilesInIndex(dest_dir): 2461c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'commit', '-m', 247cb12295daa313fcefcfff1681c30f3fe935e762eTorne (Richard Coles) 'Exclude unwanted directories'], 2481c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) cwd=dest_dir) 249f2e9853ae82a5b792ddf1af7c7d8924e9cb8c9b4Primiano Tucci assert(root_sha1 is None or root_sha1 == merged_sha1) 250f2e9853ae82a5b792ddf1af7c7d8924e9cb8c9b4Primiano Tucci return merged_sha1 2513c67328c9fd2fd48405af3950e59893bfdf1287bTorne (Richard Coles) 2523ec6f231ebe47f01e8fada97209d1b888d757615Torne (Richard Coles) 2533ec6f231ebe47f01e8fada97209d1b888d757615Torne (Richard Coles)def _CheckLicenses(): 2543ec6f231ebe47f01e8fada97209d1b888d757615Torne (Richard Coles) """Check that no incompatibly licensed directories exist.""" 2559df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) directories_left_over = webview_licenses.GetIncompatibleDirectories() 2569df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) if directories_left_over: 257862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) raise merge_common.TemporaryMergeError( 258862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) 'Incompatibly licensed directories remain: ' + 259862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) '\n'.join(directories_left_over)) 2606a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 2616a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 262f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles)def _GenerateMakefiles(version, unattended): 26382c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) """Run gyp to generate the Android build system makefiles. 2646a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 26582c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) Args: 266f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) version: The version to mention in generated commit messages. 267862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) unattended: Run in unattended mode. 26882c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) """ 2694098e8316ddaa5b20fd8f97438fd063a5468db0eTorne (Richard Coles) logging.debug('Generating makefiles ...') 2704098e8316ddaa5b20fd8f97438fd063a5468db0eTorne (Richard Coles) 271d7fe98f16c652eb648ff5668a2d81858458c18f6Richard Coles # TODO(torne): come up with a way to deal with hooks from DEPS properly 272d7fe98f16c652eb648ff5668a2d81858458c18f6Richard Coles 2739df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) # TODO(torne): The .tmp files are generated by 2746a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) # third_party/WebKit/Source/WebCore/WebCore.gyp/WebCore.gyp into the source 2756a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) # tree. We should avoid this, or at least use a more specific name to avoid 2766a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) # accidentally removing or adding other files. 2771c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) for path in merge_common.ALL_PROJECTS: 2781c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) dest_dir = os.path.join(merge_common.REPOSITORY_ROOT, path) 2791c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'rm', '--ignore-unmatch', 2805568eda06be15d573395eaba779d62c09f6f96f1Torne (Richard Coles) 'GypAndroid.*.mk', '*.target.*.mk', 2815568eda06be15d573395eaba779d62c09f6f96f1Torne (Richard Coles) '*.host.*.mk', '*.tmp'], cwd=dest_dir) 2821c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) 283862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) try: 2841f39fd6f96da9ebacdf3462306f3aef6dec2ec0bTorne (Richard Coles) merge_common.GetCommandStdout(['android_webview/tools/gyp_webview', 'all']) 2852735b74c930c17d39cb6510c0c2c0a43df1d181aTorne (Richard Coles) except merge_common.MergeError as e: 286862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) if not unattended: 287862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) raise 288862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) else: 289862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) for path in merge_common.ALL_PROJECTS: 290862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) merge_common.GetCommandStdout( 291862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) ['git', 'reset', '--hard'], 292862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) cwd=os.path.join(merge_common.REPOSITORY_ROOT, path)) 2932735b74c930c17d39cb6510c0c2c0a43df1d181aTorne (Richard Coles) raise merge_common.TemporaryMergeError('Makefile generation failed: ' + 29472724a6d44b1f9ebc7e122045a72f3502185844dTorne (Richard Coles) str(e)) 2951c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) 2961c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) for path in merge_common.ALL_PROJECTS: 2971c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) dest_dir = os.path.join(merge_common.REPOSITORY_ROOT, path) 2989df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) # git add doesn't have an --ignore-unmatch so we have to do this instead: 2995568eda06be15d573395eaba779d62c09f6f96f1Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'add', '-f', 'GypAndroid.*.mk'], 3001c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) ignore_errors=True, cwd=dest_dir) 3015568eda06be15d573395eaba779d62c09f6f96f1Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'add', '-f', '*.target.*.mk'], 3021c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) ignore_errors=True, cwd=dest_dir) 3035568eda06be15d573395eaba779d62c09f6f96f1Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'add', '-f', '*.host.*.mk'], 3041c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) ignore_errors=True, cwd=dest_dir) 3051c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'add', '-f', '*.tmp'], 3061c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) ignore_errors=True, cwd=dest_dir) 3079df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) # Only try to commit the makefiles if something has actually changed. 3089df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) if _ModifiedFilesInIndex(dest_dir): 30982c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) merge_common.GetCommandStdout( 31082c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) ['git', 'commit', '-m', 311f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) 'Update makefiles after merge of Chromium at %s\n\n%s' % 312f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) (version, AUTOGEN_MESSAGE)], cwd=dest_dir) 3136a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 3149df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) 3151c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles)def _ModifiedFilesInIndex(cwd=merge_common.REPOSITORY_ROOT): 31682c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) """Returns true if git's index contains any changes.""" 3171c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) status = merge_common.GetCommandStdout(['git', 'status', '--porcelain'], 3181c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) cwd=cwd) 31982c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) return re.search(r'^[MADRC]', status, flags=re.MULTILINE) is not None 3206a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 3216a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 322f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles)def _GenerateNoticeFile(version): 32382c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) """Generates and commits a NOTICE file containing code licenses. 32482c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 32582c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) This covers all third-party code (from Android's perspective) that lives in 32682c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) the Chromium tree. 32782c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 3286a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) Args: 329f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) version: The version to mention in generated commit messages. 3306a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) """ 3315d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) logging.debug('Regenerating NOTICE file ...') 3326a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 3339df6a6c4638cfab15aa303682c15050a9509eb44Torne (Richard Coles) contents = webview_licenses.GenerateNoticeFile() 3346a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 3351c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) with open(os.path.join(merge_common.REPOSITORY_ROOT, 'NOTICE'), 'w') as f: 3366a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) f.write(contents) 3371c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'add', 'NOTICE']) 3386a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) # Only try to commit the NOTICE update if the file has actually changed. 3396a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) if _ModifiedFilesInIndex(): 3401c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout([ 3416a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 'git', 'commit', '-m', 342f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) 'Update NOTICE file after merge of Chromium at %s\n\n%s' 343f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) % (version, AUTOGEN_MESSAGE)]) 3446a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 3456a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 346753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tuccidef _GenerateLastChange(version, root_sha1): 34782c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) """Write a build/util/LASTCHANGE file containing the current revision. 34882c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 34982c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) The revision number is compiled into the binary at build time from this file. 35082c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 351e9d946910fc23e839e0ba89df0a59cdcd1aac8ddTorne (Richard Coles) Args: 352f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) version: The version to mention in generated commit messages. 353753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci root_sha1: The SHA1 of the main project (before the merge). 354e9d946910fc23e839e0ba89df0a59cdcd1aac8ddTorne (Richard Coles) """ 3555d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) logging.debug('Updating LASTCHANGE ...') 3561c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) with open(os.path.join(merge_common.REPOSITORY_ROOT, 'build/util/LASTCHANGE'), 3571c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) 'w') as f: 35870e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci f.write('LASTCHANGE=%s\n' % merge_common.Abbrev(root_sha1)) 3591c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout(['git', 'add', '-f', 'build/util/LASTCHANGE']) 360d52d6a84a5dc0ba5264915b2e1524f65d1841b3bTorne (Richard Coles) logging.debug('Updating LASTCHANGE.blink ...') 361d52d6a84a5dc0ba5264915b2e1524f65d1841b3bTorne (Richard Coles) with open(os.path.join(merge_common.REPOSITORY_ROOT, 362d52d6a84a5dc0ba5264915b2e1524f65d1841b3bTorne (Richard Coles) 'build/util/LASTCHANGE.blink'), 'w') as f: 363d52d6a84a5dc0ba5264915b2e1524f65d1841b3bTorne (Richard Coles) f.write('LASTCHANGE=%s\n' % _GetBlinkRevision()) 364d52d6a84a5dc0ba5264915b2e1524f65d1841b3bTorne (Richard Coles) merge_common.GetCommandStdout(['git', 'add', '-f', 365d52d6a84a5dc0ba5264915b2e1524f65d1841b3bTorne (Richard Coles) 'build/util/LASTCHANGE.blink']) 366e9d946910fc23e839e0ba89df0a59cdcd1aac8ddTorne (Richard Coles) if _ModifiedFilesInIndex(): 3671c263f2b522bcb9159547d14f9f57abac46967c7Torne (Richard Coles) merge_common.GetCommandStdout([ 368e9d946910fc23e839e0ba89df0a59cdcd1aac8ddTorne (Richard Coles) 'git', 'commit', '-m', 369f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) 'Update LASTCHANGE file after merge of Chromium at %s\n\n%s' 370f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) % (version, AUTOGEN_MESSAGE)]) 371e9d946910fc23e839e0ba89df0a59cdcd1aac8ddTorne (Richard Coles) 372e9d946910fc23e839e0ba89df0a59cdcd1aac8ddTorne (Richard Coles) 373a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liudef GetHEAD(): 374753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci """Fetch the latest HEAD revision from the Chromium Git mirror. 375a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu 376a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu Returns: 377753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci The latest HEAD revision (A Git abbrev SHA1). 378a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu """ 379753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci return _GetGitAbbrevSHA1(SRC_GIT_BRANCH, 'HEAD') 380a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu 381a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu 3823977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liudef _ParseSvnRevisionFromGitCommitMessage(commit_message): 3833977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu return re.search(r'^git-svn-id: .*@([0-9]+)', commit_message, 3843977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu flags=re.MULTILINE).group(1) 3853977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu 3863977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu 387753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tuccidef _GetGitAbbrevSHA1(git_branch, revision): 38870e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci """Returns an abbrev. SHA for the given revision (or branch, if HEAD).""" 38970e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci assert revision 39070e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci logging.debug('Getting Git revision for %s ...', revision) 391753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci 392753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci upstream = git_branch if revision == 'HEAD' else revision 3933977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu 394d7b0b1b361c4cc745274a6e754b0ef2d57c73c4bPrimiano Tucci # Make sure the remote and the branch exist locally. 395d7b0b1b361c4cc745274a6e754b0ef2d57c73c4bPrimiano Tucci try: 396d7b0b1b361c4cc745274a6e754b0ef2d57c73c4bPrimiano Tucci merge_common.GetCommandStdout([ 397d7b0b1b361c4cc745274a6e754b0ef2d57c73c4bPrimiano Tucci 'git', 'show-ref', '--verify', '--quiet', git_branch]) 398d7b0b1b361c4cc745274a6e754b0ef2d57c73c4bPrimiano Tucci except merge_common.CommandError: 399d7b0b1b361c4cc745274a6e754b0ef2d57c73c4bPrimiano Tucci raise merge_common.TemporaryMergeError( 400d7b0b1b361c4cc745274a6e754b0ef2d57c73c4bPrimiano Tucci 'Cannot find the branch %s. Have you sync\'d master-chromium in this ' 401d7b0b1b361c4cc745274a6e754b0ef2d57c73c4bPrimiano Tucci 'checkout?' % git_branch) 402d7b0b1b361c4cc745274a6e754b0ef2d57c73c4bPrimiano Tucci 403753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci # Make sure the |upstream| Git object has been mirrored. 404753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci try: 405753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci merge_common.GetCommandStdout([ 406753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci 'git', 'merge-base', '--is-ancestor', upstream, git_branch]) 407753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci except merge_common.CommandError: 408753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci raise merge_common.TemporaryMergeError( 409753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci 'Upstream object (%s) not reachable from %s' % (upstream, git_branch)) 4103977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu 41170e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci abbrev_sha = merge_common.Abbrev(merge_common.GetCommandStdout( 41270e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci ['git', 'rev-list', '--max-count=1', upstream]).split()[0]) 41370e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci return abbrev_sha 4146a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 4156a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 416d52d6a84a5dc0ba5264915b2e1524f65d1841b3bTorne (Richard Coles)def _GetBlinkRevision(): 41770e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci # TODO(primiano): Switch to Git as soon as Blink gets migrated as well. 41870e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci commit = merge_common.GetCommandStdout( 41970e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci ['git', 'log', '-n1', '--grep=git-svn-id:', '--format=%H%n%b'], 420d52d6a84a5dc0ba5264915b2e1524f65d1841b3bTorne (Richard Coles) cwd=os.path.join(merge_common.REPOSITORY_ROOT, 'third_party', 'WebKit')) 421d52d6a84a5dc0ba5264915b2e1524f65d1841b3bTorne (Richard Coles) return _ParseSvnRevisionFromGitCommitMessage(commit) 422d52d6a84a5dc0ba5264915b2e1524f65d1841b3bTorne (Richard Coles) 423d52d6a84a5dc0ba5264915b2e1524f65d1841b3bTorne (Richard Coles) 424753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tuccidef Snapshot(root_sha1, release, target, unattended, buildspec_url): 42582c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) """Takes a snapshot of the Chromium tree and merges it into Android. 42682c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 42782c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) Android makefiles and a top-level NOTICE file are generated and committed 42882c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) after the merge. 42982c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) 4306a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) Args: 431753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci root_sha1: The abbrev sha1 in the Chromium git mirror to merge from. 432f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) release: The Chromium release version to merge from (e.g. "30.0.1599.20"). 433753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci Only one of root_sha1 and release should be specified. 434f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) target: The target branch to merge to. 43514ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) unattended: Run in unattended mode. 436f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) buildspec_url: URL for buildspec repository, used when merging a release. 4376a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 43882c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) Returns: 43982c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) True if new commits were merged; False if no new commits were present. 44082c98161b9cd8e8f94e00d89b6fd56540473b3d4Torne (Richard Coles) """ 441753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci if release: 442f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) root_sha1 = None 443753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci version = release 444f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) else: 445753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci root_sha1 = _GetGitAbbrevSHA1(SRC_GIT_BRANCH, root_sha1) 446753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci version = root_sha1 447753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci 44870e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci assert (root_sha1 is not None and len(root_sha1) > 6) or version == release 449753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci 450753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci if root_sha1 and not merge_common.GetCommandStdout( 451753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci ['git', 'rev-list', '-1', 'HEAD..' + root_sha1]): 45270e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci logging.info('No new commits to merge at %s (%s)', version, root_sha1) 453753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci return False 454f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) 455f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) logging.info('Snapshotting Chromium at %s (%s)', version, root_sha1) 4566a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 4576a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) # 1. Merge, accounting for excluded directories 458f2e9853ae82a5b792ddf1af7c7d8924e9cb8c9b4Primiano Tucci merged_sha1 = _MergeProjects(version, root_sha1, target, unattended, 459f2e9853ae82a5b792ddf1af7c7d8924e9cb8c9b4Primiano Tucci buildspec_url) 4606a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 4613ec6f231ebe47f01e8fada97209d1b888d757615Torne (Richard Coles) # 2. Generate Android makefiles 462f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) _GenerateMakefiles(version, unattended) 4633ec6f231ebe47f01e8fada97209d1b888d757615Torne (Richard Coles) 4643ec6f231ebe47f01e8fada97209d1b888d757615Torne (Richard Coles) # 3. Check for incompatible licenses 4653ec6f231ebe47f01e8fada97209d1b888d757615Torne (Richard Coles) _CheckLicenses() 4663ec6f231ebe47f01e8fada97209d1b888d757615Torne (Richard Coles) 4673ec6f231ebe47f01e8fada97209d1b888d757615Torne (Richard Coles) # 4. Generate Android NOTICE file 468f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) _GenerateNoticeFile(version) 4696a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 4703ec6f231ebe47f01e8fada97209d1b888d757615Torne (Richard Coles) # 5. Generate LASTCHANGE file 471f2e9853ae82a5b792ddf1af7c7d8924e9cb8c9b4Primiano Tucci _GenerateLastChange(version, merged_sha1) 472e9d946910fc23e839e0ba89df0a59cdcd1aac8ddTorne (Richard Coles) 4731896d5d734a45c412f47fe58816665d374617d3bTorne (Richard Coles) return True 4741896d5d734a45c412f47fe58816665d374617d3bTorne (Richard Coles) 4756a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 476f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles)def Push(version, target): 477bda7cff5dd92725ba000fe95d9434f81a7af486eTorne (Richard Coles) """Push the finished snapshot to the Android repository.""" 478f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) src = 'merge-from-chromium-%s' % version 4793b1480d1d7d07cb989630cd5767f439dd3f5fabdTorne (Richard Coles) # Use forced pushes ('+' prefix) for the temporary and archive branches in 4803b1480d1d7d07cb989630cd5767f439dd3f5fabdTorne (Richard Coles) # case they already got updated by a previous (possibly failed?) merge, but 4813b1480d1d7d07cb989630cd5767f439dd3f5fabdTorne (Richard Coles) # do not force push to the real master-chromium branch as this could erase 4823b1480d1d7d07cb989630cd5767f439dd3f5fabdTorne (Richard Coles) # downstream changes. 483f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) refspecs = ['%s:%s' % (src, target), 484f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) '+%s:refs/archive/chromium-%s' % (src, version)] 485f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) if target == 'master-chromium': 486f533bc666f11273be2d7a211be4cda18d53bf0a3Torne (Richard Coles) refspecs.insert(0, '+%s:master-chromium-merge' % src) 487f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) for refspec in refspecs: 48870e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci logging.debug('Pushing to server (%s) ...', refspec) 48909ead754abd2cfcffea54040b1c9ac98db8af834Torne (Richard Coles) for path in merge_common.ALL_PROJECTS: 49009ead754abd2cfcffea54040b1c9ac98db8af834Torne (Richard Coles) if path in merge_common.PROJECTS_WITH_FLAT_HISTORY: 49109ead754abd2cfcffea54040b1c9ac98db8af834Torne (Richard Coles) remote = 'history' 49209ead754abd2cfcffea54040b1c9ac98db8af834Torne (Richard Coles) else: 49309ead754abd2cfcffea54040b1c9ac98db8af834Torne (Richard Coles) remote = 'goog' 49409ead754abd2cfcffea54040b1c9ac98db8af834Torne (Richard Coles) logging.debug('Pushing %s', path) 49509ead754abd2cfcffea54040b1c9ac98db8af834Torne (Richard Coles) dest_dir = os.path.join(merge_common.REPOSITORY_ROOT, path) 4963b1480d1d7d07cb989630cd5767f439dd3f5fabdTorne (Richard Coles) merge_common.GetCommandStdout(['git', 'push', remote, refspec], 4973b1480d1d7d07cb989630cd5767f439dd3f5fabdTorne (Richard Coles) cwd=dest_dir) 498bda7cff5dd92725ba000fe95d9434f81a7af486eTorne (Richard Coles) 499bda7cff5dd92725ba000fe95d9434f81a7af486eTorne (Richard Coles) 5006a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles)def main(): 5016a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) parser = optparse.OptionParser(usage='%prog [options]') 5026a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) parser.epilog = ('Takes a snapshot of the Chromium tree at the specified ' 503753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci 'Chromium Git revision and merges it into this repository. ' 5046a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 'Paths marked as excluded for license reasons are removed ' 5056a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 'as part of the merge. Also generates Android makefiles and ' 5066a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 'generates a top-level NOTICE file suitable for use in the ' 5076a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 'Android build.') 5086a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) parser.add_option( 5093977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu '', '--sha1', 510753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci default='HEAD', 511753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci help=('Merge to the specified chromium sha1 revision from ' + 512753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci SRC_GIT_BRANCH + ' branch. Default is HEAD, to merge from ToT.')) 513f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) parser.add_option( 514f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) '', '--release', 515f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) default=None, 516753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci help=('Merge to the specified chromium release buildspec (e.g., "30.0.' 517753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci '1599.20"). Only one of --sha1 and --release should be specified')) 518f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) parser.add_option( 519f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) '', '--buildspec_url', 520f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) default=None, 521f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) help=('Git URL for buildspec repository.')) 522f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) parser.add_option( 523f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) '', '--target', 524f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) default='master-chromium', metavar='BRANCH', 525f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) help=('Target branch to push to. Defaults to master-chromium.')) 5261896d5d734a45c412f47fe58816665d374617d3bTorne (Richard Coles) parser.add_option( 52714ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) '', '--push', 52814ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) default=False, action='store_true', 5293977434d5c3aafc00eaae0d2e78fa8ddd72536f3Bo Liu help=('Push the result of a previous merge to the server. Note ' 530753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci '--sha1 must be given.')) 5319fb672be51066b51a372885377cc0eff78e1a34cTorne (Richard Coles) parser.add_option( 532a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu '', '--get_head', 533a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu default=False, action='store_true', 534a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu help=('Just print the current HEAD revision on stdout and exit.')) 535a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu parser.add_option( 53614ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) '', '--unattended', 5371896d5d734a45c412f47fe58816665d374617d3bTorne (Richard Coles) default=False, action='store_true', 53814ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) help=('Run in unattended mode.')) 539d2a42d0b062f4c9bb4c3fefc80cde98350b5974eTorne (Richard Coles) parser.add_option( 540d2a42d0b062f4c9bb4c3fefc80cde98350b5974eTorne (Richard Coles) '', '--no_changes_exit', 541d2a42d0b062f4c9bb4c3fefc80cde98350b5974eTorne (Richard Coles) default=0, type='int', 542d2a42d0b062f4c9bb4c3fefc80cde98350b5974eTorne (Richard Coles) help=('Exit code to use if there are no changes to merge, for scripts.')) 5436a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) (options, args) = parser.parse_args() 5446a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) if args: 5456a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) parser.print_help() 5466a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) return 1 5476a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 5486a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) if 'ANDROID_BUILD_TOP' not in os.environ: 5496a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) print >>sys.stderr, 'You need to run the Android envsetup.sh and lunch.' 5506a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) return 1 5516a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 552d7b0b1b361c4cc745274a6e754b0ef2d57c73c4bPrimiano Tucci if os.environ.get('GYP_DEFINES'): 553d7b0b1b361c4cc745274a6e754b0ef2d57c73c4bPrimiano Tucci print >>sys.stderr, ( 554d7b0b1b361c4cc745274a6e754b0ef2d57c73c4bPrimiano Tucci 'The environment is defining GYP_DEFINES (=%s). It will affect the ' 555d7b0b1b361c4cc745274a6e754b0ef2d57c73c4bPrimiano Tucci ' generated makefiles.' % os.environ['GYP_DEFINES']) 556d7b0b1b361c4cc745274a6e754b0ef2d57c73c4bPrimiano Tucci if not options.unattended and raw_input('Continue? [y/N]') != 'y': 557d7b0b1b361c4cc745274a6e754b0ef2d57c73c4bPrimiano Tucci return 1 558d7b0b1b361c4cc745274a6e754b0ef2d57c73c4bPrimiano Tucci 5595d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) logging.basicConfig(format='%(message)s', level=logging.DEBUG, 5605d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) stream=sys.stdout) 5615d65b76f6747f51bb623d00205aca85581ad4d91Torne (Richard Coles) 562753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci if options.get_head: 563a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu logging.disable(logging.CRITICAL) # Prevent log messages 564a611c7e365068e2130b6de87b2b14e3b75ae1d4eBo Liu print GetHEAD() 5659fb672be51066b51a372885377cc0eff78e1a34cTorne (Richard Coles) elif options.push: 566f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) if options.release: 567f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) Push(options.release, options.target) 568753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci elif options.sha1: 569753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci Push(options.sha1, options.target) 570862edb04ee66c65ce977d9b14b8809aad40749acTorne (Richard Coles) else: 571f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) print >>sys.stderr, 'You need to pass the version to push.' 572f81a1ea8129a3a620d677d6eeab99d2727367c88Torne (Richard Coles) return 1 57314ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) else: 574753233e1666d4a8f69a4fae4345f9590f19589efPrimiano Tucci if not Snapshot(options.sha1, options.release, options.target, 57570e496d940c22bf07cd2c5634e1819276ddac416Primiano Tucci options.unattended, options.buildspec_url): 576d2a42d0b062f4c9bb4c3fefc80cde98350b5974eTorne (Richard Coles) return options.no_changes_exit 57714ac2c8d49fa1f5f12e6a80af93f1c50312d80a8Torne (Richard Coles) 5786a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) return 0 5796a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) 5806a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles)if __name__ == '__main__': 5816a8c82cdaffde31477cacabea89afefeded67f3eTorne (Richard Coles) sys.exit(main()) 582