| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/env python | |
| 2 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 """ Create (if needed) and sync a nested checkout of Skia inside of Chrome. """ | |
| 7 | |
| 8 from config_private import SKIA_GIT_URL | |
| 9 from optparse import OptionParser | |
| 10 from py.utils.git_utils import GIT | |
| 11 from py.utils import git_utils | |
| 12 from py.utils import misc | |
| 13 from py.utils import shell_utils | |
| 14 | |
| 15 import gclient_utils | |
| 16 import os | |
| 17 import re | |
| 18 import shlex | |
| 19 import sys | |
| 20 import urllib2 | |
| 21 | |
| 22 | |
| 23 CHROME_GIT_URL = 'https://chromium.googlesource.com/chromium/src.git' | |
| 24 CHROME_LKGR_URL = 'http://chromium-status.appspot.com/git-lkgr' | |
| 25 FETCH = 'fetch.bat' if os.name == 'nt' else 'fetch' | |
| 26 GCLIENT = 'gclient.bat' if os.name == 'nt' else 'gclient' | |
| 27 GCLIENT_FILE = '.gclient' | |
| 28 PATH_TO_SKIA_IN_CHROME = os.path.join('src', 'third_party', 'skia', 'src') | |
| 29 DEFAULT_FETCH_TARGET = 'chromium' | |
| 30 | |
| 31 # Sync Chrome to LKGR. | |
| 32 CHROME_REV_LKGR = 'CHROME_REV_LKGR' | |
| 33 # Sync Chrome to origin/master. | |
| 34 CHROME_REV_MASTER = 'CHROME_REV_MASTER' | |
| 35 | |
| 36 # Code revision specified by DEPS. | |
| 37 SKIA_REV_DEPS = 'SKIA_REV_DEPS' | |
| 38 # Sync to origin/master. | |
| 39 SKIA_REV_MASTER = 'SKIA_REV_MASTER' | |
| 40 | |
| 41 | |
| 42 def GetDepsVar(deps_filepath, variable): | |
| 43 """Read the given DEPS file and return the value of the given variable. | |
| 44 | |
| 45 Args: | |
| 46 deps_filepath: string; path to a DEPS file. | |
| 47 variable: string; name of the variable whose value should be returned. | |
| 48 Returns: | |
| 49 string; value of the requested variable. | |
| 50 """ | |
| 51 deps_vars = {} | |
| 52 deps_vars['Var'] = lambda x: deps_vars['vars'][x] | |
| 53 execfile(deps_filepath, deps_vars) | |
| 54 return deps_vars['vars'][variable] | |
| 55 | |
| 56 | |
| 57 def Sync(skia_revision=SKIA_REV_MASTER, chrome_revision=CHROME_REV_LKGR, | |
| 58 fetch_target=DEFAULT_FETCH_TARGET, | |
| 59 gyp_defines=None, gyp_generators=None): | |
| 60 """ Create and sync a checkout of Skia inside a checkout of Chrome. Returns | |
| 61 a tuple containing the actually-obtained revision of Skia and the actually- | |
| 62 obtained revision of Chrome. | |
| 63 | |
| 64 skia_revision: revision of Skia to sync. Should be a commit hash or one of | |
| 65 (SKIA_REV_DEPS, SKIA_REV_MASTER). | |
| 66 chrome_revision: revision of Chrome to sync. Should be a commit hash or one | |
| 67 of (CHROME_REV_LKGR, CHROME_REV_MASTER). | |
| 68 fetch_target: string; Calls the fetch tool in depot_tools with the specified | |
| 69 argument. Default is DEFAULT_FETCH_TARGET. | |
| 70 gyp_defines: optional string; GYP_DEFINES to be passed to Gyp. | |
| 71 gyp_generators: optional string; which GYP_GENERATORS to use. | |
| 72 """ | |
| 73 # Figure out what revision of Skia we should use. | |
| 74 if skia_revision == SKIA_REV_MASTER: | |
| 75 output = git_utils.GetRemoteMasterHash(SKIA_GIT_URL) | |
| 76 if output: | |
| 77 skia_revision = shlex.split(output)[0] | |
| 78 if not skia_revision: | |
| 79 raise Exception('Could not determine current Skia revision!') | |
| 80 skia_revision = str(skia_revision) | |
| 81 | |
| 82 # Use Chrome LKGR, since gclient_utils will force a sync to origin/master. | |
| 83 if chrome_revision == CHROME_REV_LKGR: | |
| 84 chrome_revision = urllib2.urlopen(CHROME_LKGR_URL).read() | |
| 85 elif chrome_revision == CHROME_REV_MASTER: | |
| 86 chrome_revision = shlex.split( | |
| 87 git_utils.GetRemoteMasterHash(CHROME_GIT_URL))[0] | |
| 88 | |
| 89 # Run "fetch chromium". The initial run is allowed to fail after it does some | |
| 90 # work. At the least, we expect the .gclient file to be present when it | |
| 91 # finishes. | |
| 92 if not os.path.isfile(GCLIENT_FILE): | |
| 93 try: | |
| 94 shell_utils.run([FETCH, fetch_target, '--nosvn=True']) | |
| 95 except shell_utils.CommandFailedException: | |
| 96 pass | |
| 97 if not os.path.isfile(GCLIENT_FILE): | |
| 98 raise Exception('Could not fetch %s!' % fetch_target) | |
| 99 | |
| 100 # Run "gclient sync" | |
| 101 revisions = [('src', chrome_revision)] | |
| 102 if skia_revision != SKIA_REV_DEPS: | |
| 103 revisions.append(('src/third_party/skia', skia_revision)) | |
| 104 | |
| 105 try: | |
| 106 # Hack: We have to set some GYP_DEFINES, or upstream scripts will complain. | |
| 107 os.environ['GYP_DEFINES'] = os.environ.get('GYP_DEFINES') or '' | |
| 108 gclient_utils.Sync( | |
| 109 revisions=revisions, | |
| 110 jobs=1, | |
| 111 no_hooks=True, | |
| 112 force=True) | |
| 113 except shell_utils.CommandFailedException as e: | |
| 114 # We frequently see sync failures because a lock file wasn't deleted. In | |
| 115 # that case, delete the lock file and try again. | |
| 116 pattern = r".*fatal: Unable to create '(\S+)': File exists\..*" | |
| 117 match = re.search(pattern, e.output) | |
| 118 if not match: | |
| 119 raise e | |
| 120 file_to_delete = match.groups()[0] | |
| 121 try: | |
| 122 print 'Attempting to remove %s' % file_to_delete | |
| 123 os.remove(file_to_delete) | |
| 124 except OSError: | |
| 125 # If the file no longer exists, just try again. | |
| 126 pass | |
| 127 gclient_utils.Sync( | |
| 128 revisions=revisions, | |
| 129 jobs=1, | |
| 130 no_hooks=True, | |
| 131 force=True) | |
| 132 | |
| 133 # Find the actually-obtained Chrome revision. | |
| 134 os.chdir('src') | |
| 135 actual_chrome_rev = shell_utils.run([GIT, 'rev-parse', 'HEAD'], | |
| 136 log_in_real_time=False).rstrip() | |
| 137 | |
| 138 | |
| 139 # Find the actually-obtained Skia revision. | |
| 140 with misc.ChDir(os.path.join('third_party', 'skia')): | |
| 141 actual_skia_rev = shell_utils.run([GIT, 'rev-parse', 'HEAD'], | |
| 142 log_in_real_time=False).rstrip() | |
| 143 | |
| 144 # Run gclient hooks | |
| 145 gclient_utils.RunHooks(gyp_defines=gyp_defines, gyp_generators=gyp_generators) | |
| 146 | |
| 147 # Fix the submodules so that they don't show up in "git status" | |
| 148 # This fails on Windows... | |
| 149 if os.name != 'nt': | |
| 150 submodule_cmd = ('\'git config -f ' | |
| 151 '$toplevel/.git/config submodule.$name.ignore all\'') | |
| 152 shell_utils.run(' '.join([GIT, 'submodule', 'foreach', submodule_cmd]), | |
| 153 shell=True) | |
| 154 | |
| 155 # Verify that we got the requested revisions of Chrome and Skia. | |
| 156 if skia_revision != actual_skia_rev and skia_revision != SKIA_REV_DEPS: | |
| 157 raise Exception('Requested Skia revision %s but got %s!' % ( | |
| 158 repr(skia_revision), repr(actual_skia_rev))) | |
| 159 if chrome_revision and chrome_revision != actual_chrome_rev: | |
| 160 raise Exception('Requested Chrome revision %s but got %s!' % ( | |
| 161 repr(chrome_revision), repr(actual_chrome_rev))) | |
| 162 | |
| 163 return (actual_skia_rev, actual_chrome_rev) | |
| 164 | |
| 165 | |
| 166 def Main(): | |
| 167 parser = OptionParser() | |
| 168 parser.add_option('--skia_revision', | |
| 169 help=('Desired revision of Skia. Defaults to the most ' | |
| 170 'recent revision.')) | |
| 171 parser.add_option('--chrome_revision', | |
| 172 help=('Desired revision of Chrome. Defaults to the most ' | |
| 173 'recent revision.')) | |
| 174 parser.add_option('--destination', | |
| 175 help=('Where to sync the code. Defaults to the current ' | |
| 176 'directory.'), | |
| 177 default=os.curdir) | |
| 178 parser.add_option('--fetch_target', | |
| 179 help=('Calls the fetch tool in depot_tools with the ' | |
| 180 'specified target.'), | |
| 181 default=DEFAULT_FETCH_TARGET) | |
| 182 (options, _) = parser.parse_args() | |
| 183 dest_dir = os.path.abspath(options.destination) | |
| 184 with misc.ChDir(dest_dir): | |
| 185 actual_skia_rev, actual_chrome_rev = Sync( | |
| 186 skia_revision=options.skia_revision or SKIA_REV_MASTER, | |
| 187 chrome_revision=options.chrome_revision or CHROME_REV_MASTER, | |
| 188 fetch_target=options.fetch_target) | |
| 189 print 'Chrome synced to %s' % actual_chrome_rev | |
| 190 print 'Skia synced to %s' % actual_skia_rev | |
| 191 | |
| 192 | |
| 193 if __name__ == '__main__': | |
| 194 sys.exit(Main()) | |
| OLD | NEW |