Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2014 The Chromium Authors. All rights reserved. | 2 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 | 6 import codecs |
| 7 import copy | 7 import copy |
| 8 import json | |
| 8 import optparse | 9 import optparse |
| 9 import os | 10 import os |
| 11 import pprint | |
| 12 import shutil | |
| 13 import socket | |
| 14 import subprocess | |
| 10 import sys | 15 import sys |
| 16 import time | |
| 11 import urlparse | 17 import urlparse |
| 12 | 18 |
| 19 import os.path as path | |
| 20 | |
| 13 | 21 |
| 14 RECOGNIZED_PATHS = { | 22 RECOGNIZED_PATHS = { |
| 15 # If SVN path matches key, the entire URL is rewritten to the Git url. | 23 # If SVN path matches key, the entire URL is rewritten to the Git url. |
| 16 '/chrome/trunk/src': | 24 '/chrome/trunk/src': |
| 17 'https://chromium.googlesource.com/chromium/src.git', | 25 'https://chromium.googlesource.com/chromium/src.git', |
| 18 '/chrome-internal/trunk/src-internal': | 26 '/chrome-internal/trunk/src-internal': |
| 19 'https://chrome-internal.googlesource.com/chrome/src-internal.git' | 27 'https://chrome-internal.googlesource.com/chrome/src-internal.git' |
| 20 } | 28 } |
| 21 | 29 |
| 22 | 30 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 44 The bot will perform a Git checkout in this step. | 52 The bot will perform a Git checkout in this step. |
| 45 The "gclient revert" and "update" steps are no-ops. | 53 The "gclient revert" and "update" steps are no-ops. |
| 46 | 54 |
| 47 """ | 55 """ |
| 48 | 56 |
| 49 NOT_ACTIVATED_MESSAGE = """INACTIVE. | 57 NOT_ACTIVATED_MESSAGE = """INACTIVE. |
| 50 This step does nothing. You actually want to look at the "update" step. | 58 This step does nothing. You actually want to look at the "update" step. |
| 51 | 59 |
| 52 """ | 60 """ |
| 53 | 61 |
| 62 | |
| 63 GCLIENT_TEMPLATE = """solutions = %(solutions)s | |
| 64 | |
| 65 cache_dir = %(cache_dir)s | |
| 66 """ | |
| 67 | |
| 54 ENABLED_MASTERS = ['chromium.git'] | 68 ENABLED_MASTERS = ['chromium.git'] |
| 55 # Master: Builders dict. | |
| 56 ENABLED_BUILDERS = {} | 69 ENABLED_BUILDERS = {} |
| 57 # Master: Slaves dict. | |
| 58 ENABLED_SLAVES = {} | 70 ENABLED_SLAVES = {} |
| 59 | 71 |
| 60 # Disabled filters get run AFTER enabled filters, so for example if a builder | 72 # Disabled filters get run AFTER enabled filters, so for example if a builder |
| 61 # config is enabled, but a bot on that builder is disabled, that bot will | 73 # config is enabled, but a bot on that builder is disabled, that bot will |
| 62 # be disabled. | 74 # be disabled. |
| 63 DISABLED_BUILDERS = {} | 75 DISABLED_BUILDERS = {} |
| 64 DISABLED_SLAVES = {} | 76 DISABLED_SLAVES = {} |
| 65 | 77 |
| 78 # How many times to retry failed subprocess calls. | |
| 79 RETRIES = 3 | |
| 80 | |
| 81 SCRIPTS_PATH = path.dirname(path.dirname(path.abspath(__file__))) | |
| 82 DEPS2GIT_DIR_PATH = path.join(SCRIPTS_PATH, 'tools', 'deps2git') | |
| 83 DEPS2GIT_PATH = path.join(DEPS2GIT_DIR_PATH, 'deps2git.py') | |
| 84 S2G_INTERNAL_FROM_PATH = path.join(SCRIPTS_PATH, 'tools', 'deps2git_internal', | |
| 85 'svn_to_git_internal.py') | |
| 86 S2G_INTERNAL_DEST_PATH = path.join(DEPS2GIT_DIR_PATH, 'svn_to_git_internal.py') | |
| 87 | |
| 88 # ../../cache_dir aka /b/build/slave/cache_dir | |
| 89 CACHE_DIR = os.path.join( | |
|
agable
2014/02/07 22:19:06
could do this relative to SCRIPTS_DIR. Probably sh
iannucci
2014/02/07 22:24:09
* THIS_DIR = path.abspath(path.dirname(__file__))
Ryan Tseng
2014/02/07 22:27:50
Done.
| |
| 90 os.path.dirname(os.path.dirname(os.path.abspath(os.getcwd()))), | |
| 91 'cache_dir') | |
| 92 | |
| 93 | |
| 94 class SubprocessFailed(Exception): | |
| 95 pass | |
| 96 | |
| 97 | |
| 98 def call(*args): | |
| 99 """Interactive subprocess call.""" | |
| 100 tries = 0 | |
| 101 while tries < RETRIES: | |
| 102 tries_msg = '(retry #%d)' % tries if tries else '' | |
| 103 print '===Running %s%s===' % (' '.join(args), tries_msg) | |
| 104 start_time = time.time() | |
| 105 proc = subprocess.Popen(args, stdout=subprocess.PIPE, | |
| 106 stderr=subprocess.STDOUT) | |
| 107 # This is here because passing 'sys.stdout' into stdout for proc will | |
| 108 # produce out of order output. | |
| 109 while True: | |
| 110 buf = proc.stdout.read(1) | |
| 111 if not buf: | |
| 112 break | |
| 113 sys.stdout.write(buf) | |
| 114 code = proc.wait() | |
| 115 elapsed_time = ((time.time() - start_time) / 60.0) | |
| 116 if not code: | |
| 117 print '===Succeeded in %.1f mins===' % elapsed_time | |
| 118 print | |
| 119 break | |
| 120 print '===Failed in %.1f mins===' % elapsed_time | |
| 121 print | |
| 122 tries += 1 | |
| 123 | |
| 124 if code: | |
| 125 raise SubprocessFailed('%s failed with code %d in %s' % | |
| 126 (' '.join(args), code, os.getcwd())) | |
| 127 return code | |
| 128 | |
| 129 | |
| 130 def get_gclient_spec(solutions): | |
| 131 return GCLIENT_TEMPLATE % { | |
| 132 'solutions': pprint.pformat(solutions, indent=4), | |
| 133 'cache_dir': '"%s"' % CACHE_DIR | |
| 134 } | |
| 135 | |
| 66 | 136 |
| 67 def check_enabled(master, builder, slave): | 137 def check_enabled(master, builder, slave): |
| 68 if master in ENABLED_MASTERS: | 138 if master in ENABLED_MASTERS: |
| 69 return True | 139 return True |
| 70 builder_list = ENABLED_BUILDERS.get(master) | 140 builder_list = ENABLED_BUILDERS.get(master) |
| 71 if builder_list and builder in builder_list: | 141 if builder_list and builder in builder_list: |
| 72 return True | 142 return True |
| 73 slave_list = ENABLED_SLAVES.get(master) | 143 slave_list = ENABLED_SLAVES.get(master) |
| 74 if slave_list and slave in slave_list: | 144 if slave_list and slave in slave_list: |
| 75 return True | 145 return True |
| 76 return False | 146 return False |
| 77 | 147 |
| 78 | 148 |
| 79 def check_disabled(master, builder, slave): | 149 def check_disabled(master, builder, slave): |
| 80 """Returns True if disabled, False if not disabled.""" | 150 """Returns True if disabled, False if not disabled.""" |
| 81 builder_list = DISABLED_BUILDERS.get(master) | 151 builder_list = DISABLED_BUILDERS.get(master) |
| 82 if builder_list and builder in builder_list: | 152 if builder_list and builder in builder_list: |
| 83 return True | 153 return True |
| 84 slave_list = DISABLED_SLAVES.get(master) | 154 slave_list = DISABLED_SLAVES.get(master) |
| 85 if slave_list and slave in slave_list: | 155 if slave_list and slave in slave_list: |
| 86 return True | 156 return True |
| 87 return False | 157 return False |
| 88 | 158 |
| 89 | 159 |
| 90 def check_valid_host(master, builder, slave): | 160 def check_valid_host(master, builder, slave): |
| 91 return False | 161 return (check_enabled(master, builder, slave) |
| 162 and not check_disabled(master, builder, slave)) | |
| 92 | 163 |
| 93 | 164 |
| 94 def solutions_printer(solutions): | 165 def solutions_printer(solutions): |
| 95 """Prints gclient solution to stdout.""" | 166 """Prints gclient solution to stdout.""" |
| 96 print 'Gclient Solutions' | 167 print 'Gclient Solutions' |
| 97 print '=================' | 168 print '=================' |
| 98 for solution in solutions: | 169 for solution in solutions: |
| 99 name = solution.get('name') | 170 name = solution.get('name') |
| 100 url = solution.get('url') | 171 url = solution.get('url') |
| 101 print '%s (%s)' % (name, url) | 172 print '%s (%s)' % (name, url) |
| 173 if solution.get('deps_file'): | |
| 174 print ' Dependencies file is %s' % solution['deps_file'] | |
| 175 if 'managed' in solution: | |
| 176 print ' Managed mode is %s' % ('ON' if solution['managed'] else 'OFF') | |
| 102 custom_vars = solution.get('custom_vars') | 177 custom_vars = solution.get('custom_vars') |
| 103 if custom_vars: | 178 if custom_vars: |
| 104 print ' Custom Variables:' | 179 print ' Custom Variables:' |
| 105 for var_name, var_value in sorted(custom_vars.iteritems()): | 180 for var_name, var_value in sorted(custom_vars.iteritems()): |
| 106 print ' %s = %s' % (var_name, var_value) | 181 print ' %s = %s' % (var_name, var_value) |
| 107 custom_deps = solution.get('custom_deps') | 182 custom_deps = solution.get('custom_deps') |
| 108 if 'custom_deps' in solution: | 183 if 'custom_deps' in solution: |
| 109 print ' Custom Dependencies:' | 184 print ' Custom Dependencies:' |
| 110 for deps_name, deps_value in sorted(custom_deps.iteritems()): | 185 for deps_name, deps_value in sorted(custom_deps.iteritems()): |
| 111 if deps_value: | 186 if deps_value: |
| 112 print ' %s -> %s' % (deps_name, deps_value) | 187 print ' %s -> %s' % (deps_name, deps_value) |
| 113 else: | 188 else: |
| 114 print ' %s: Ignore' % deps_name | 189 print ' %s: Ignore' % deps_name |
| 115 if solution.get('deps_file'): | |
| 116 print ' Dependencies file is %s' % solution['deps_file'] | |
| 117 if 'managed' in solution: | |
| 118 print ' Managed mode is %s' % ('ON' if solution['managed'] else 'OFF') | |
| 119 print | 190 print |
| 120 | 191 |
| 121 | 192 |
| 122 def solutions_to_git(input_solutions): | 193 def solutions_to_git(input_solutions): |
| 123 """Modifies urls in solutions to point at Git repos.""" | 194 """Modifies urls in solutions to point at Git repos.""" |
| 124 solutions = copy.deepcopy(input_solutions) | 195 solutions = copy.deepcopy(input_solutions) |
| 125 for solution in solutions: | 196 for solution in solutions: |
| 126 original_url = solution['url'] | 197 original_url = solution['url'] |
| 127 parsed_url = urlparse.urlparse(original_url) | 198 parsed_url = urlparse.urlparse(original_url) |
| 128 path = parsed_url.path | 199 path = parsed_url.path |
| 129 if path in RECOGNIZED_PATHS: | 200 if path in RECOGNIZED_PATHS: |
| 130 solution['url'] = RECOGNIZED_PATHS[path] | 201 solution['url'] = RECOGNIZED_PATHS[path] |
| 131 else: | 202 else: |
| 132 print 'Warning: path %s not recognized' % path | 203 print 'Warning: path %s not recognized' % path |
| 133 if solution.get('deps_file', 'DEPS') == 'DEPS': | 204 if solution.get('deps_file', 'DEPS') == 'DEPS': |
| 134 solution['deps_file'] = '.DEPS.git' | 205 solution['deps_file'] = '.DEPS.git' |
| 135 solution['managed'] = False | 206 solution['managed'] = False |
| 136 return solutions | 207 return solutions |
| 137 | 208 |
| 138 | 209 |
| 139 def ensure_no_git_checkout(): | 210 def ensure_no_checkout(dir_names, scm_dirname): |
| 140 """Ensure that there is no git checkout under build/. | 211 """Ensure that there is no git checkout under build/. |
| 141 | 212 |
| 142 If there is a git checkout under build/, then move build/ to build.dead/ | 213 If there is an incorrect checkout under build/, then |
| 214 move build/ to build.dead/ | |
| 215 This function will check each directory in dir_names. | |
| 216 | |
| 217 scm_dirname is expected to be either ['.svn', '.git'] | |
| 143 """ | 218 """ |
| 144 pass | 219 assert scm_dirname in ['.svn', '.git'] |
| 220 has_checkout = any(map(lambda dir_name: path.exists( | |
| 221 path.join(os.getcwd(), dir_name, scm_dirname)), dir_names)) | |
| 145 | 222 |
| 223 if has_checkout: | |
| 224 # cd .. && rm -rf ./build && mkdir ./build && cd build | |
| 225 build_dir = os.getcwd() | |
| 146 | 226 |
| 147 def ensure_no_svn_checkout(): | 227 os.chdir(path.dirname(os.getcwd())) |
| 148 """Ensure that there is no svn checkout under build/. | 228 print '%s detected in checking, deleting %s...' % (scm_dirname, build_dir), |
| 229 shutil.rmtree(build_dir) | |
| 230 print 'done' | |
| 231 os.mkdir(build_dir) | |
| 232 os.chdir(build_dir) | |
| 149 | 233 |
| 150 If there is a svn checkout under build/, then move build/ to build.dead/ | |
| 151 """ | |
| 152 pass | |
| 153 | 234 |
| 154 | 235 |
| 155 def gclient_configure(solutions): | 236 def gclient_configure(solutions): |
| 156 pass | 237 """Should do the same thing as gclient --spec='...'.""" |
| 238 with codecs.open('.gclient', mode='w', encoding='utf-8') as f: | |
| 239 f.write(get_gclient_spec(solutions)) | |
| 157 | 240 |
| 158 | 241 |
| 159 def gclient_shallow_sync(): | 242 def gclient_sync(): |
| 160 pass | 243 call('gclient', 'sync', '--verbose', '--reset', '--force', |
| 244 '--nohooks', '--noprehooks') | |
| 161 | 245 |
| 162 | 246 |
| 163 def git_pull_and_clean(): | 247 def get_git_hash(revision, dir_name): |
| 164 pass | 248 match = "^git-svn-id: [^ ]*@%d" % revision |
| 249 cmd = ['git', 'log', '--grep', match, '--format=%H', dir_name] | |
| 250 return subprocess.check_output(cmd).strip() or None | |
| 251 | |
| 252 | |
| 253 def deps2git(sln_dirs): | |
| 254 for sln_dir in sln_dirs: | |
| 255 deps_file = path.join(os.getcwd(), sln_dir, 'DEPS') | |
| 256 deps_git_file = path.join(os.getcwd(), sln_dir, '.DEPS.git') | |
| 257 if not path.isfile(deps_file): | |
| 258 return | |
| 259 # Do we have a better way of doing this....? | |
| 260 repo_type = 'internal' if 'internal' in sln_dir else 'public' | |
| 261 # TODO(hinoka): This will be what populates the git caches on the first | |
| 262 # run for all of the bots. Since deps2git is single threaded, | |
| 263 # all of this will run in a single threaded context and be | |
| 264 # super slow. Should make deps2git multithreaded. | |
| 265 call(sys.executable, DEPS2GIT_PATH, '-t', repo_type, | |
| 266 '--cache_dir=%s' % CACHE_DIR, | |
| 267 '--deps=%s' % deps_file, '--out=%s' % deps_git_file) | |
| 268 | |
| 269 | |
| 270 def git_checkout(solutions, revision): | |
| 271 build_dir = os.getcwd() | |
| 272 # Revision only applies to the first solution. | |
| 273 first_solution = True | |
| 274 for sln in solutions: | |
| 275 name = sln['name'] | |
| 276 url = sln['url'] | |
| 277 sln_dir = path.join(build_dir, name) | |
| 278 if not path.isdir(sln_dir): | |
| 279 call('git', 'clone', url, sln_dir) | |
| 280 | |
| 281 # Clean out .DEPS.git changes first. | |
| 282 call('git', '-C', sln_dir, 'reset', '--hard') | |
| 283 call('git', '-C', sln_dir, 'clean', '-df') | |
| 284 call('git', '-C', sln_dir, 'pull', 'origin', 'master') | |
| 285 # TODO(hinoka): We probably have to make use of revision mapping. | |
| 286 if first_solution and revision and revision.lower() != 'head': | |
| 287 if revision and revision.isdigit() and len(revision) < 40: | |
| 288 # rev_num is really a svn revision number, convert it into a git hash. | |
| 289 git_hash = get_git_hash(revision, name) | |
| 290 else: | |
| 291 # rev_num is actually a git hash or ref, we can just use it. | |
| 292 git_hash = revision | |
|
agable
2014/02/07 22:19:06
Since we're willing to use refs (HEAD, master, my-
Ryan Tseng
2014/02/07 22:27:50
Done.
| |
| 293 call('git', '-C', sln_dir, 'checkout', git_hash) | |
| 294 else: | |
| 295 call('git', '-C', sln_dir, 'checkout', 'origin/master') | |
| 296 | |
| 297 # Force another clean, because why not. | |
| 298 call('git', '-C', sln_dir, 'clean', '-df') | |
|
agable
2014/02/07 22:19:06
Only do this if you really think it's necessary. S
iannucci
2014/02/07 22:24:09
Isn't this necessary because there could be a patc
Ryan Tseng
2014/02/07 22:27:50
The one on line 283 is probably enough. I'll remov
| |
| 299 | |
| 300 first_solution = False | |
| 165 | 301 |
| 166 | 302 |
| 167 def apply_issue(issue, patchset, root, server): | 303 def apply_issue(issue, patchset, root, server): |
| 168 pass | 304 pass |
| 169 | 305 |
| 170 | 306 |
| 171 def deps2git(): | 307 def delete_flag(flag_file): |
| 172 pass | 308 """Remove bot update flag.""" |
| 309 if os.path.exists(flag_file): | |
| 310 os.remove(flag_file) | |
| 173 | 311 |
| 174 | 312 |
| 175 def gclient_sync(): | 313 def emit_flag(flag_file): |
| 176 pass | |
| 177 | |
| 178 | |
| 179 def deposit_bot_update_flag(): | |
| 180 """Deposit a bot update flag on the system to tell gclient not to run.""" | 314 """Deposit a bot update flag on the system to tell gclient not to run.""" |
| 181 pass | 315 print 'Emitting flag file at %s' % flag_file |
| 316 with open(flag_file, 'wb') as f: | |
| 317 f.write('Success!') | |
| 182 | 318 |
| 183 | 319 |
| 184 def parse_args(): | 320 def parse_args(): |
| 185 parse = optparse.OptionParser() | 321 parse = optparse.OptionParser() |
| 186 | 322 |
| 187 parse.add_option('-i', '--issue', help='Issue number to patch from.') | 323 parse.add_option('-i', '--issue', help='Issue number to patch from.') |
| 188 parse.add_option('-p', '--patchset', | 324 parse.add_option('-p', '--patchset', |
| 189 help='Patchset from issue to patch from, if applicable.') | 325 help='Patchset from issue to patch from, if applicable.') |
| 190 parse.add_option('-r', '--root', help='Repository root.') | 326 parse.add_option('-r', '--root', help='Repository root.') |
| 191 parse.add_option('-c', '--server', help='Rietveld server.') | 327 parse.add_option('-c', '--server', help='Rietveld server.') |
| 192 parse.add_option('-s', '--specs', help='Gcilent spec.') | 328 parse.add_option('-s', '--specs', help='Gcilent spec.') |
| 193 parse.add_option('-m', '--master', help='Master name.') | 329 parse.add_option('-m', '--master', help='Master name.') |
| 194 parse.add_option('-f', '--force', action='store_true', | 330 parse.add_option('-f', '--force', action='store_true', |
| 195 help='Bypass check to see if we want to be run. ' | 331 help='Bypass check to see if we want to be run. ' |
| 196 'Should ONLY be used locally.') | 332 'Should ONLY be used locally.') |
| 333 # TODO(hinoka): We don't actually use this | |
|
agable
2014/02/07 22:19:06
Then can we remove it? Or does that require a mast
iannucci
2014/02/07 22:24:09
We probably shouldn't rely on this being a paramet
Ryan Tseng
2014/02/07 22:27:50
Rephrased. I mean we need to use this at some poi
| |
| 197 parse.add_option('-e', '--revision-mapping') | 334 parse.add_option('-e', '--revision-mapping') |
| 335 parse.add_option('-v', '--revision') | |
| 336 parse.add_option('-b', '--build_dir', default=os.getcwd()) | |
| 337 parse.add_option('-g', '--flag_file', default=path.join(os.getcwd(), | |
| 338 'update.flag')) | |
| 198 | 339 |
| 199 return parse.parse_args() | 340 return parse.parse_args() |
| 200 | 341 |
| 201 | 342 |
| 202 def main(): | 343 def main(): |
| 203 # Get inputs. | 344 # Get inputs. |
| 204 options, _ = parse_args() | 345 options, _ = parse_args() |
| 205 builder = os.environ.get('BUILDBOT_BUILDERNAME', None) | 346 builder = os.environ.get('BUILDBOT_BUILDERNAME', None) |
| 206 slave = os.environ.get('BUILDBOT_SLAVENAME', None) | 347 slave = os.environ.get('BUILDBOT_SLAVENAME', socket.getfqdn().split('.')[0]) |
| 207 master = options.master | 348 master = options.master |
| 349 if not options.revision: | |
| 350 options.revision = os.environ.get('BUILDBOT_REVISION') | |
| 208 | 351 |
| 209 # Check if this script should activate or not. | 352 # Check if this script should activate or not. |
| 210 active = check_valid_host(master, builder, slave) or options.force | 353 active = check_valid_host(master, builder, slave) or options.force |
| 211 | 354 |
| 212 # Print helpful messages to tell devs whats going on. | 355 # Print helpful messages to tell devs whats going on. |
| 213 print BOT_UPDATE_MESSAGE % { | 356 print BOT_UPDATE_MESSAGE % { |
| 214 'master': master, | 357 'master': master, |
| 215 'builder': builder, | 358 'builder': builder, |
| 216 'slave': slave, | 359 'slave': slave, |
| 217 }, | 360 }, |
| 218 # Print to stderr so that it shows up red on win/mac. | 361 # Print to stderr so that it shows up red on win/mac. |
| 219 print ACTIVATED_MESSAGE if active else NOT_ACTIVATED_MESSAGE | 362 print ACTIVATED_MESSAGE if active else NOT_ACTIVATED_MESSAGE |
| 220 | 363 |
| 221 # Parse, munipulate, and print the gclient solutions. | 364 # Parse, munipulate, and print the gclient solutions. |
| 222 specs = {} | 365 specs = {} |
| 223 exec(options.specs, specs) # TODO(hinoka): LOL this is terrible. | 366 exec(options.specs, specs) |
| 224 solutions = specs.get('solutions', []) | 367 svn_solutions = specs.get('solutions', []) |
| 225 git_solutions = solutions_to_git(solutions) | 368 git_solutions = solutions_to_git(svn_solutions) |
| 226 solutions_printer(git_solutions) | 369 solutions_printer(git_solutions) |
| 227 | 370 |
| 228 # Do the checkout. | 371 # Cleanup svn checkout if active, otherwise remove git checkout and exit. |
| 229 # TODO(hinoka): Uncomment these once they're implemented. | 372 dir_names = [sln.get('name') for sln in svn_solutions if 'name' in sln] |
| 230 # ensure_no_svn_checkout() | 373 if active: |
| 231 # gclient_configure(git_solutions) | 374 ensure_no_checkout(dir_names, '.svn') |
| 232 # gclient_shallow_sync() | 375 emit_flag(options.flag_file) |
| 233 # git_pull_and_clean() | 376 else: |
| 377 ensure_no_checkout(dir_names, '.git') | |
| 378 delete_flag(options.flag_file) | |
| 379 return | |
| 380 | |
| 381 # Get a checkout of each solution, without DEPS or hooks. | |
| 382 # Calling git directory because there is no way to run Gclient without | |
| 383 # invoking DEPS. | |
| 384 print 'Fetching Git checkout' | |
| 385 git_checkout(git_solutions, options.revision) | |
| 386 | |
| 387 # TODO(hinoka): This must be implemented before we can turn this on for TS. | |
| 234 # if options.issue: | 388 # if options.issue: |
| 235 # apply_issue(options.issue, options.patchset, options.root, options.server) | 389 # apply_issue(options.issue, options.patchset, options.root, options.server) |
| 236 # deps2git() | 390 |
| 237 # gclient_sync() | 391 # Magic to get deps2git to work with internal DEPS. |
| 392 shutil.copyfile(S2G_INTERNAL_FROM_PATH, S2G_INTERNAL_DEST_PATH) | |
| 393 deps2git(dir_names) | |
| 394 | |
| 395 gclient_configure(git_solutions) | |
| 396 gclient_sync() | |
| 238 | 397 |
| 239 | 398 |
| 240 if __name__ == '__main__': | 399 if __name__ == '__main__': |
| 241 sys.exit(main()) | 400 sys.exit(main()) |
| OLD | NEW |