| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/env python | |
| 2 # Copyright (c) 2012 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 """ Check out the Skia sources. """ | |
| 7 | |
| 8 | |
| 9 from build_step import BuildStep, BuildStepFailure | |
| 10 | |
| 11 from common import chromium_utils | |
| 12 from py.utils.git_utils import GIT | |
| 13 from utils import file_utils | |
| 14 from utils import gclient_utils | |
| 15 from py.utils import misc | |
| 16 from py.utils import shell_utils | |
| 17 | |
| 18 import ast | |
| 19 import config_private | |
| 20 import os | |
| 21 import re | |
| 22 import sys | |
| 23 | |
| 24 | |
| 25 LOCAL_GIT_MIRROR_URL = 'http://192.168.1.120/git-mirror/skia' | |
| 26 SKIA_GIT_URL_TO_REPLACE = config_private.SKIA_GIT_URL[:-len('.git')] | |
| 27 | |
| 28 | |
| 29 def _MaybeUseSkiaLabMirror(revision=None): | |
| 30 """If the SkiaLab mirror is reachable, set the gitconfig to use that instead | |
| 31 of the remote repo. | |
| 32 | |
| 33 Args: | |
| 34 revision: optional string; commit hash to which we're syncing. This is a | |
| 35 safety net; in the case that the mirror does not yet have this commit, | |
| 36 we will use the remote repo instead. | |
| 37 """ | |
| 38 # Attempt to reach the SkiaLab git mirror. | |
| 39 mirror_is_accessible = False | |
| 40 print 'Attempting to reach the SkiaLab git mirror...' | |
| 41 try: | |
| 42 shell_utils.run([GIT, 'ls-remote', | |
| 43 LOCAL_GIT_MIRROR_URL + '.git', | |
| 44 revision or 'HEAD', '--exit-code'], timeout=10) | |
| 45 mirror_is_accessible = True | |
| 46 except (shell_utils.CommandFailedException, shell_utils.TimeoutException): | |
| 47 pass | |
| 48 | |
| 49 # Find the global git config entries and loop over them, removing the ones | |
| 50 # which aren't needed and adding a URL override for the git mirror if it is | |
| 51 # accessible and not already present. | |
| 52 try: | |
| 53 configs = shell_utils.run([GIT, 'config', '--global', | |
| 54 '--list']).splitlines() | |
| 55 except shell_utils.CommandFailedException: | |
| 56 configs = [] | |
| 57 | |
| 58 already_overriding_url = False | |
| 59 for config in configs: | |
| 60 override_url = None | |
| 61 match = re.match('url.(.+).insteadof=', config) | |
| 62 if match: | |
| 63 override_url = match.groups()[0] | |
| 64 if override_url: | |
| 65 if override_url == LOCAL_GIT_MIRROR_URL and mirror_is_accessible: | |
| 66 print 'Already have URL override for SkiaLab git mirror.' | |
| 67 already_overriding_url = True | |
| 68 else: | |
| 69 print 'Removing unneeded URL override for %s' % override_url | |
| 70 try: | |
| 71 shell_utils.run([GIT, 'config', '--global', | |
| 72 '--remove-section', config.split('.insteadof')[0]]) | |
| 73 except shell_utils.CommandFailedException as e: | |
| 74 if 'No such section!' in e.output: | |
| 75 print '"insteadof" section already removed; continuing...' | |
| 76 else: | |
| 77 raise | |
| 78 | |
| 79 if mirror_is_accessible and not already_overriding_url: | |
| 80 print ('SkiaLab git mirror appears to be accessible. Changing gitconfig to ' | |
| 81 'use the mirror.') | |
| 82 shell_utils.run([GIT, 'config', '--global', | |
| 83 'url.%s.insteadOf' % LOCAL_GIT_MIRROR_URL, | |
| 84 SKIA_GIT_URL_TO_REPLACE]) | |
| 85 | |
| 86 # Some debugging info that might help us figure things out... | |
| 87 try: | |
| 88 shell_utils.run([GIT, 'config', '--global', '--list']) | |
| 89 except shell_utils.CommandFailedException: | |
| 90 pass | |
| 91 | |
| 92 | |
| 93 class Update(BuildStep): | |
| 94 def __init__(self, timeout=10000, no_output_timeout=6000, attempts=5, | |
| 95 **kwargs): | |
| 96 super(Update, self).__init__(timeout=timeout, | |
| 97 no_output_timeout=no_output_timeout, | |
| 98 attempts=attempts, | |
| 99 **kwargs) | |
| 100 | |
| 101 def _Run(self): | |
| 102 # Run "gclient" before doing anything else to ensure that we get the | |
| 103 # necessary stuff installed. | |
| 104 gclient_utils.GClient() | |
| 105 | |
| 106 _MaybeUseSkiaLabMirror(self._revision) | |
| 107 | |
| 108 # We receive gclient_solutions as a list of dictionaries flattened into a | |
| 109 # double-quoted string. This invocation of literal_eval converts that string | |
| 110 # into a list of strings. | |
| 111 solutions = ast.literal_eval(self._args['gclient_solutions'][1:-1]) | |
| 112 | |
| 113 # TODO(borenet): Move the gclient solutions parsing logic into a function. | |
| 114 | |
| 115 # Parse each solution dictionary from a string and add it to a list, while | |
| 116 # building a string to pass as a spec to gclient, to indicate which | |
| 117 # branches should be downloaded. | |
| 118 solution_dicts = [] | |
| 119 gclient_spec = 'solutions = [' | |
| 120 for solution in solutions: | |
| 121 gclient_spec += solution | |
| 122 solution_dicts += ast.literal_eval(solution) | |
| 123 gclient_spec += ']' | |
| 124 | |
| 125 # Set the DEPS target_os if necessary. | |
| 126 if self._deps_target_os: | |
| 127 gclient_spec += '\ntarget_os = ["%s"]' % self._deps_target_os | |
| 128 | |
| 129 # Run "gclient config" with the spec we just built. | |
| 130 gclient_utils.Config(spec=gclient_spec) | |
| 131 | |
| 132 revisions = [] | |
| 133 for solution in solution_dicts: | |
| 134 if solution['name'] == gclient_utils.SKIA_TRUNK: | |
| 135 revisions.append((solution['name'], self._revision)) | |
| 136 else: | |
| 137 url_split = solution['url'].split('@') | |
| 138 if len(url_split) > 1: | |
| 139 revision = url_split[1] | |
| 140 revisions.append((solution['name'], revision)) | |
| 141 | |
| 142 try: | |
| 143 if self._is_try: | |
| 144 # Clean our checkout to make sure we don't have a patch left over. | |
| 145 if (os.path.isdir('skia') and | |
| 146 os.path.isdir(os.path.join('skia', '.git'))): | |
| 147 with misc.ChDir('skia'): | |
| 148 gclient_utils.Revert() | |
| 149 | |
| 150 # Run "gclient sync" | |
| 151 gclient_utils.Sync( | |
| 152 revisions=revisions, | |
| 153 verbose=True, | |
| 154 force=True, | |
| 155 delete_unversioned_trees=True) | |
| 156 got_revision = gclient_utils.GetCheckedOutHash() | |
| 157 except Exception: | |
| 158 # If the sync fails, clear the checkout and try again. | |
| 159 print 'Initial sync failed.' | |
| 160 # Attempt to remove the skia directory first. | |
| 161 if os.path.isdir('skia'): | |
| 162 print 'Removing "skia"' | |
| 163 chromium_utils.RemoveDirectory('skia') | |
| 164 # Now, remove *everything* in the build directory. | |
| 165 build_dir = os.path.abspath(os.curdir) | |
| 166 with misc.ChDir(os.pardir): | |
| 167 print 'Attempting to clear %s' % build_dir | |
| 168 file_utils.clear_directory(build_dir) | |
| 169 # Try to sync again. | |
| 170 print 'Attempting to sync again.' | |
| 171 gclient_utils.Config(spec=gclient_spec) | |
| 172 gclient_utils.Sync( | |
| 173 revisions=revisions, | |
| 174 verbose=True, | |
| 175 force=True, | |
| 176 delete_unversioned_trees=True, | |
| 177 jobs=1) | |
| 178 got_revision = gclient_utils.GetCheckedOutHash() | |
| 179 | |
| 180 # If the revision we actually got differs from what was requested, raise an | |
| 181 # exception. | |
| 182 if self._revision and got_revision != self._revision: | |
| 183 raise BuildStepFailure('Actually-synced revision "%s" is different from ' | |
| 184 'the requested revision "%s".' % ( | |
| 185 repr(got_revision), repr(self._revision))) | |
| 186 | |
| 187 # Print the obtained revision number so that the master can parse it. | |
| 188 print 'Skia updated to %s' % got_revision | |
| 189 | |
| 190 | |
| 191 if '__main__' == __name__: | |
| 192 sys.exit(BuildStep.RunBuildStep(Update)) | |
| OLD | NEW |