Ryan Cui | b603c54 | 2011-07-27 16:00:11 -0700 | [diff] [blame] | 1 | #!/usr/bin/python |
| 2 | # Copyright (c) 2011 The Chromium OS 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 | """Script that resets your Chrome GIT checkout.""" |
| 7 | |
| 8 | import optparse |
| 9 | import os |
Ryan Cui | 7d7c88b | 2011-11-01 22:11:55 -0700 | [diff] [blame] | 10 | import re |
Ryan Cui | b603c54 | 2011-07-27 16:00:11 -0700 | [diff] [blame] | 11 | |
Brian Harring | 503f3ab | 2012-03-09 21:39:41 -0800 | [diff] [blame] | 12 | from chromite.buildbot import repository |
| 13 | from chromite.lib import cros_build_lib as cros_lib |
Ryan Cui | b603c54 | 2011-07-27 16:00:11 -0700 | [diff] [blame] | 14 | |
| 15 | |
Ryan Cui | 44360de | 2011-08-22 16:50:20 -0700 | [diff] [blame] | 16 | _CHROMIUM_ROOT = 'chromium' |
| 17 | _CHROMIUM_SRC_ROOT = os.path.join(_CHROMIUM_ROOT, 'src') |
Ryan Cui | d1024a8 | 2011-08-26 17:58:36 -0700 | [diff] [blame] | 18 | _CHROMIUM_SRC_INTERNAL = os.path.join(_CHROMIUM_ROOT, 'src-internal') |
Ryan Cui | 44360de | 2011-08-22 16:50:20 -0700 | [diff] [blame] | 19 | _CHROMIUM_CROS_DEPS = os.path.join(_CHROMIUM_SRC_ROOT, 'tools/cros.DEPS/DEPS') |
Ryan Cui | b603c54 | 2011-07-27 16:00:11 -0700 | [diff] [blame] | 20 | |
| 21 | |
| 22 | def _LoadDEPS(deps_content): |
| 23 | """Load contents of DEPS file into a dictionary. |
| 24 | |
| 25 | Arguments: |
| 26 | deps_content: The contents of the .DEPS.git file. |
| 27 | |
| 28 | Returns: |
| 29 | A dictionary indexed by the top level items in the structure - i.e., |
| 30 | 'hooks', 'deps', 'os_deps'. |
| 31 | """ |
| 32 | class FromImpl: |
| 33 | """From syntax is not supported.""" |
| 34 | def __init__(self, module_name, var_name): |
| 35 | raise NotImplementedError('The From() syntax is not supported in' |
| 36 | 'chrome_set_ver.') |
| 37 | |
| 38 | class _VarImpl: |
Ryan Cui | 446e8e7 | 2011-09-23 18:02:41 -0700 | [diff] [blame] | 39 | def __init__(self, custom_vars, local_scope): |
Ryan Cui | b603c54 | 2011-07-27 16:00:11 -0700 | [diff] [blame] | 40 | self._custom_vars = custom_vars |
| 41 | self._local_scope = local_scope |
| 42 | |
| 43 | def Lookup(self, var_name): |
| 44 | """Implements the Var syntax.""" |
| 45 | if var_name in self._custom_vars: |
| 46 | return self._custom_vars[var_name] |
| 47 | elif var_name in self._local_scope.get('vars', {}): |
| 48 | return self._local_scope['vars'][var_name] |
| 49 | raise Exception('Var is not defined: %s' % var_name) |
| 50 | |
| 51 | locals = {} |
| 52 | var = _VarImpl({}, locals) |
| 53 | globals = {'From': FromImpl, 'Var': var.Lookup, 'deps_os': {}} |
| 54 | exec(deps_content) in globals, locals |
| 55 | return locals |
| 56 | |
| 57 | |
Ryan Cui | 446e8e7 | 2011-09-23 18:02:41 -0700 | [diff] [blame] | 58 | def _CreateCrosSymlink(repo_root): |
| 59 | """Create symlinks to CrOS projects specified in the cros_DEPS/DEPS file.""" |
| 60 | cros_deps_file = os.path.join(repo_root, _CHROMIUM_CROS_DEPS) |
| 61 | _, merged_deps = GetParsedDeps(cros_deps_file) |
| 62 | chromium_root = os.path.join(repo_root, _CHROMIUM_ROOT) |
Ryan Cui | af3e2eb | 2011-09-30 16:43:03 -0700 | [diff] [blame] | 63 | |
Ryan Cui | 446e8e7 | 2011-09-23 18:02:41 -0700 | [diff] [blame] | 64 | mappings = GetPathToProjectMappings(merged_deps) |
| 65 | for rel_path, project in mappings.iteritems(): |
| 66 | link_dir = os.path.join(chromium_root, rel_path) |
| 67 | target_dir = os.path.join(repo_root, |
| 68 | cros_lib.GetProjectDir(repo_root, project)) |
| 69 | path_to_target = os.path.relpath(target_dir, os.path.dirname(link_dir)) |
| 70 | if not os.path.exists(link_dir): |
| 71 | os.symlink(path_to_target, link_dir) |
| 72 | |
| 73 | |
| 74 | def _ExtractProjectFromUrl(repo_url): |
| 75 | """Get the Gerrit project name from an url.""" |
Ryan Cui | 7d7c88b | 2011-11-01 22:11:55 -0700 | [diff] [blame] | 76 | # Example: 'ssh://gerrit-int.chromium.org:12121/my/project.git' would parse to |
| 77 | # 'my/project'. See unit test for more examples. For 'URL's like |
| 78 | # '../abc/efg' leave as-is to support unit tests. |
| 79 | mo = re.match(r'(?:[\w\+]+://[^/]+/)?(.*)', repo_url) |
| 80 | return os.path.splitext(mo.group(1))[0] |
Ryan Cui | b603c54 | 2011-07-27 16:00:11 -0700 | [diff] [blame] | 81 | |
| 82 | |
Ryan Cui | d1024a8 | 2011-08-26 17:58:36 -0700 | [diff] [blame] | 83 | def _ExtractProjectFromEntry(entry): |
| 84 | """From a deps entry extract the Gerrit project name. |
| 85 | |
| 86 | Arguments: |
Ryan Cui | 65e1f9a | 2011-09-21 17:06:43 -0700 | [diff] [blame] | 87 | entry: The deps entry in the format ${url_prefix}/${project_name}@${hash}. |
Ryan Cui | d1024a8 | 2011-08-26 17:58:36 -0700 | [diff] [blame] | 88 | """ |
| 89 | # We only support Gerrit urls, where the path is the project name. |
| 90 | repo_url = entry.partition('@')[0] |
Ryan Cui | 446e8e7 | 2011-09-23 18:02:41 -0700 | [diff] [blame] | 91 | return _ExtractProjectFromUrl(repo_url) |
Ryan Cui | d1024a8 | 2011-08-26 17:58:36 -0700 | [diff] [blame] | 92 | |
| 93 | |
| 94 | def GetPathToProjectMappings(deps): |
| 95 | """Get dictionary relating path to Gerrit project names. |
| 96 | |
| 97 | Arguments: |
| 98 | deps: a dictionary indexed by repo paths. The same format as the 'deps' |
| 99 | entry in the '.DEPS.git' file. |
| 100 | """ |
| 101 | mappings = {} |
| 102 | for rel_path, entry in deps.iteritems(): |
| 103 | mappings[rel_path] = _ExtractProjectFromEntry(entry) |
| 104 | |
| 105 | return mappings |
| 106 | |
| 107 | |
Ryan Cui | 446e8e7 | 2011-09-23 18:02:41 -0700 | [diff] [blame] | 108 | class ProjectException(Exception): |
| 109 | """Raised by Project class when a Pin error """ |
| 110 | pass |
Ryan Cui | b75c303 | 2011-08-10 16:19:39 -0700 | [diff] [blame] | 111 | |
| 112 | |
Ryan Cui | 446e8e7 | 2011-09-23 18:02:41 -0700 | [diff] [blame] | 113 | class Project(object): |
| 114 | """Encapsulates functionality to pin a project to a specific commit.""" |
| 115 | def __init__(self, repo_root, project_url, rel_path): |
| 116 | """Construct the class. |
| 117 | |
| 118 | Arguments: |
| 119 | repo_root: The root of the repo checkout. |
| 120 | project_url: The Gerrit url of the project. |
| 121 | rel_path: The path the project is expected to be checked out to. Relative |
| 122 | to <repo_root>/chromium. |
| 123 | """ |
| 124 | self.repo_root = repo_root |
| 125 | self.chromium_root = os.path.join(self.repo_root, _CHROMIUM_ROOT) |
| 126 | self.project_url = project_url |
| 127 | self.rel_path = rel_path |
| 128 | self.abs_path = os.path.join(self.chromium_root, self.rel_path) |
| 129 | self.manifest_rel_path = os.path.join(_CHROMIUM_ROOT, self.rel_path) |
| 130 | self.project_name = _ExtractProjectFromUrl(self.project_url) |
| 131 | |
| 132 | def _ResetProject(self, commit_hash): |
| 133 | """Actually pin project to the specified commit hash.""" |
| 134 | if not cros_lib.DoesCommitExistInRepo(self.abs_path, commit_hash): |
| 135 | cros_lib.Die('Commit %s not found in %s.\n' |
| 136 | "You probably need to run 'repo sync --jobs=<jobs>' " |
| 137 | 'to update your checkout.' |
| 138 | % (commit_hash, self.abs_path)) |
| 139 | |
| 140 | result = cros_lib.RunCommand(['git', 'checkout', commit_hash], |
| 141 | error_code_ok=True, cwd=self.abs_path) |
| 142 | if result.returncode != 0: |
| 143 | cros_lib.Warning('Failed to pin project %s.\n' |
| 144 | 'You probably have uncommited local changes.' |
| 145 | % self.abs_path) |
| 146 | |
| 147 | def _PrepareProject(self): |
| 148 | """Make sure the project is synced properly and is ready for pinning.""" |
David James | 1bd7fae | 2012-04-22 10:14:38 -0700 | [diff] [blame^] | 149 | handler = cros_lib.ParseFullManifest(self.repo_root) |
| 150 | path_to_project_dict = dict(([attrs['path'], project]) for project, attrs |
| 151 | in handler.projects.iteritems()) |
Ryan Cui | 446e8e7 | 2011-09-23 18:02:41 -0700 | [diff] [blame] | 152 | |
| 153 | # TODO(rcui): Handle case where a dependency never makes it to the manifest |
| 154 | # (i.e., dep path added as double checkout, and then gets deleted). We need |
| 155 | # to delete those. crosbug/22123. |
| 156 | if not cros_lib.IsDirectoryAGitRepoRoot(self.abs_path): |
| 157 | if self.manifest_rel_path in path_to_project_dict: |
| 158 | raise ProjectException('%s in full layout manifest but not in working ' |
| 159 | "tree. Please run 'repo sync %s'" |
| 160 | % (self.manifest_rel_path, |
| 161 | path_to_project_dict[self.manifest_rel_path])) |
| 162 | else: |
| 163 | cros_lib.Warning('Project %s is not in the manifest. Automatically ' |
| 164 | 'checking out to %s.\n' |
| 165 | % (self.project_url, self.abs_path)) |
| 166 | repository.CloneGitRepo(self.abs_path, self.project_url) |
| 167 | cros_lib.RunCommand(['git', 'checkout', |
| 168 | cros_lib.GetGitRepoRevision(self.abs_path)], |
| 169 | cwd=self.abs_path) |
| 170 | elif not cros_lib.IsProjectManagedByRepo(self.abs_path): |
| 171 | if self.manifest_rel_path in path_to_project_dict: |
| 172 | # If path is now in the manifest, tell user to manually delete our |
| 173 | # managed checkout and re-sync. |
| 174 | raise ProjectException('%s needs to be replaced. Please remove the ' |
| 175 | "directory and run 'repo sync %s'" |
| 176 | % (self.manifest_rel_path, |
| 177 | path_to_project_dict[self.manifest_rel_path])) |
| 178 | else: |
| 179 | # If not managed by Repo we need to perform sync. |
| 180 | cros_lib.RunCommand(['git', 'pull', '--rebase', self.project_url], |
| 181 | cwd=self.abs_path) |
| 182 | elif not os.path.islink(self.abs_path): |
| 183 | # Skip symlinks - we don't want to error out for the cros.DEPS projects. |
| 184 | if self.manifest_rel_path not in path_to_project_dict: |
| 185 | # If it is 'managed by repo' but not in the manifest, repo tried |
| 186 | # deleting it but failed because of local changes. |
| 187 | raise ProjectException('%s is no longer in the manifest but has local ' |
| 188 | 'changes. Please remove and try again.' |
| 189 | % self.manifest_rel_path) |
| 190 | elif self.project_name != path_to_project_dict[self.manifest_rel_path]: |
| 191 | cros_lib.Die('.DEPS.git for %s conflicts with manifest.xml! Running ' |
| 192 | 'with older .DEPS.git files are not yet supported. ' |
| 193 | "Please run'repo sync --jobs=<jobs>' to sync everything " |
| 194 | 'up.' % self.manifest_rel_path) |
| 195 | |
| 196 | def Pin(self, commit_hash): |
| 197 | """Attempt to pin the project to the specified commit hash. |
| 198 | |
| 199 | Arguments: |
| 200 | commit_hash: The commit to pin the project to. |
| 201 | |
| 202 | Raises: |
| 203 | ProjectException when an error occurs. |
| 204 | """ |
| 205 | self._PrepareProject() |
| 206 | if cros_lib.GetCurrentBranch(self.abs_path): |
| 207 | cros_lib.Warning("Not pinning project %s that's checked out to a " |
| 208 | 'development branch.' % self.rel_path) |
| 209 | elif (commit_hash and |
| 210 | (commit_hash != cros_lib.GetGitRepoRevision(self.abs_path))): |
| 211 | print 'Pinning project %s' % self.rel_path |
| 212 | self._ResetProject(commit_hash) |
| 213 | else: |
| 214 | cros_lib.Debug('Skipping project %s, already pinned' % self.rel_path) |
| 215 | |
| 216 | |
| 217 | def _ResetGitCheckout(repo_root, deps): |
Ryan Cui | b603c54 | 2011-07-27 16:00:11 -0700 | [diff] [blame] | 218 | """Reset chrome repos to hashes specified in the DEPS file. |
| 219 | |
| 220 | Arguments: |
| 221 | chromium_root: directory where chromium is checked out - level above 'src'. |
| 222 | deps: a dictionary indexed by repo paths. The same format as the 'deps' |
| 223 | entry in the '.DEPS.git' file. |
| 224 | """ |
Ryan Cui | 446e8e7 | 2011-09-23 18:02:41 -0700 | [diff] [blame] | 225 | errors = [] |
Ryan Cui | b603c54 | 2011-07-27 16:00:11 -0700 | [diff] [blame] | 226 | for rel_path, project_hash in deps.iteritems(): |
Ryan Cui | d1024a8 | 2011-08-26 17:58:36 -0700 | [diff] [blame] | 227 | repo_url, _, commit_hash = project_hash.partition('@') |
Ryan Cui | 446e8e7 | 2011-09-23 18:02:41 -0700 | [diff] [blame] | 228 | project = Project(repo_root, repo_url, rel_path) |
| 229 | try: |
| 230 | project.Pin(commit_hash) |
| 231 | except ProjectException as e: |
| 232 | errors.append(str(e)) |
Ryan Cui | 65e1f9a | 2011-09-21 17:06:43 -0700 | [diff] [blame] | 233 | |
Ryan Cui | 446e8e7 | 2011-09-23 18:02:41 -0700 | [diff] [blame] | 234 | if errors: |
| 235 | cros_lib.Die('Errors encountered:\n* ' + '\n* '.join(errors)) |
Ryan Cui | b603c54 | 2011-07-27 16:00:11 -0700 | [diff] [blame] | 236 | |
| 237 | |
| 238 | def _RunHooks(chromium_root, hooks): |
| 239 | """Run the hooks contained in the DEPS file. |
| 240 | |
| 241 | Arguments: |
| 242 | chromium_root: directory where chromium is checked out - level above 'src'. |
| 243 | hooks: a list of hook dictionaries. The same format as the 'hooks' entry |
| 244 | in the '.DEPS.git' file. |
| 245 | """ |
| 246 | for hook in hooks: |
Ryan Cui | af3e2eb | 2011-09-30 16:43:03 -0700 | [diff] [blame] | 247 | print '[running hook] %s' % ' '.join(hook['action']) |
Ryan Cui | b603c54 | 2011-07-27 16:00:11 -0700 | [diff] [blame] | 248 | cros_lib.RunCommand(hook['action'], cwd=chromium_root) |
| 249 | |
| 250 | |
Ryan Cui | 44360de | 2011-08-22 16:50:20 -0700 | [diff] [blame] | 251 | def _MergeDeps(dest, update): |
| 252 | """Merge the dependencies specified in two dictionaries. |
| 253 | |
| 254 | Arguments: |
| 255 | dest: The dictionary that will be merged into. |
| 256 | update: The dictionary whose elements will be merged into dest. |
| 257 | """ |
| 258 | assert(not set(dest.keys()).intersection(set(update.keys()))) |
| 259 | dest.update(update) |
| 260 | return dest |
| 261 | |
| 262 | |
Ryan Cui | 97b2f30 | 2011-10-24 17:34:05 -0700 | [diff] [blame] | 263 | def GetParsedDeps(deps_file): |
Ryan Cui | 6c85111 | 2011-08-11 21:51:37 -0700 | [diff] [blame] | 264 | """Returns the full parsed DEPS file dictionary, and merged deps. |
| 265 | |
| 266 | Arguments: |
Ryan Cui | 65e1f9a | 2011-09-21 17:06:43 -0700 | [diff] [blame] | 267 | deps_file: Path to the .DEPS.git file. |
Ryan Cui | 6c85111 | 2011-08-11 21:51:37 -0700 | [diff] [blame] | 268 | |
| 269 | Returns: |
| 270 | An (x,y) tuple. x is a dictionary containing the contents of the DEPS file, |
| 271 | and y is a dictionary containing the result of merging unix and common deps. |
| 272 | """ |
| 273 | with open(deps_file, 'rU') as f: |
| 274 | deps = _LoadDEPS(f.read()) |
| 275 | |
Ryan Cui | 44360de | 2011-08-22 16:50:20 -0700 | [diff] [blame] | 276 | merged_deps = deps.get('deps', {}) |
Ryan Cui | d1024a8 | 2011-08-26 17:58:36 -0700 | [diff] [blame] | 277 | unix_deps = deps.get('deps_os', {}).get('unix', {}) |
Ryan Cui | 44360de | 2011-08-22 16:50:20 -0700 | [diff] [blame] | 278 | merged_deps = _MergeDeps(merged_deps, unix_deps) |
Ryan Cui | 6c85111 | 2011-08-11 21:51:37 -0700 | [diff] [blame] | 279 | return deps, merged_deps |
| 280 | |
| 281 | |
Brian Harring | 3067505 | 2012-02-29 12:18:22 -0800 | [diff] [blame] | 282 | def main(argv): |
Ryan Cui | b603c54 | 2011-07-27 16:00:11 -0700 | [diff] [blame] | 283 | |
Ryan Cui | 9ef7c92 | 2011-08-17 11:48:02 -0700 | [diff] [blame] | 284 | usage = 'usage: %prog [-d <DEPS.git file>] [command]' |
| 285 | parser = optparse.OptionParser(usage=usage) |
Ryan Cui | 6c85111 | 2011-08-11 21:51:37 -0700 | [diff] [blame] | 286 | |
Ryan Cui | 65e1f9a | 2011-09-21 17:06:43 -0700 | [diff] [blame] | 287 | # TODO(rcui): have -d accept a URL. |
Ryan Cui | b603c54 | 2011-07-27 16:00:11 -0700 | [diff] [blame] | 288 | parser.add_option('-d', '--deps', default=None, |
| 289 | help=('DEPS file to use. Defaults to ' |
| 290 | '<chrome_src_root>/.DEPS.git')) |
| 291 | parser.add_option('--internal', action='store_false', dest='internal', |
| 292 | default=True, help='Allow chrome-internal URLs') |
Ryan Cui | 9ef7c92 | 2011-08-17 11:48:02 -0700 | [diff] [blame] | 293 | parser.add_option('--runhooks', action='store_true', dest='runhooks', |
| 294 | default=False, help="Run hooks as well.") |
Ryan Cui | 65e1f9a | 2011-09-21 17:06:43 -0700 | [diff] [blame] | 295 | parser.add_option('-v', '--verbose', default=False, action='store_true', |
| 296 | help='Run with debug output.') |
Ryan Cui | 446e8e7 | 2011-09-23 18:02:41 -0700 | [diff] [blame] | 297 | (options, _inputs) = parser.parse_args(argv) |
Ryan Cui | b603c54 | 2011-07-27 16:00:11 -0700 | [diff] [blame] | 298 | |
Ryan Cui | 65e1f9a | 2011-09-21 17:06:43 -0700 | [diff] [blame] | 299 | # Set cros_build_lib debug level to hide RunCommand spew. |
| 300 | if options.verbose: |
| 301 | cros_lib.DebugLevel.SetDebugLevel(cros_lib.DebugLevel.DEBUG) |
| 302 | else: |
| 303 | cros_lib.DebugLevel.SetDebugLevel(cros_lib.DebugLevel.WARNING) |
| 304 | |
Ryan Cui | e52602e | 2011-11-03 15:54:35 -0700 | [diff] [blame] | 305 | if cros_lib.IsInsideChroot(): |
| 306 | ssh_path = '/usr/bin/ssh_no_update' |
| 307 | if os.path.isfile(ssh_path): |
| 308 | os.environ['GIT_SSH'] = ssh_path |
| 309 | else: |
| 310 | cros_lib.Warning("Can't find %s. Run build_packages or setup_board to " |
| 311 | 'update your chooot.' % ssh_path) |
| 312 | |
Ryan Cui | b75c303 | 2011-08-10 16:19:39 -0700 | [diff] [blame] | 313 | repo_root = cros_lib.FindRepoCheckoutRoot() |
| 314 | chromium_src_root = os.path.join(repo_root, _CHROMIUM_SRC_ROOT) |
Ryan Cui | b603c54 | 2011-07-27 16:00:11 -0700 | [diff] [blame] | 315 | if not os.path.isdir(chromium_src_root): |
Ryan Cui | 6c85111 | 2011-08-11 21:51:37 -0700 | [diff] [blame] | 316 | cros_lib.Die('chromium src/ dir not found') |
Ryan Cui | b603c54 | 2011-07-27 16:00:11 -0700 | [diff] [blame] | 317 | |
Ryan Cui | 65e1f9a | 2011-09-21 17:06:43 -0700 | [diff] [blame] | 318 | # Add DEPS files to parse. |
Ryan Cui | 44360de | 2011-08-22 16:50:20 -0700 | [diff] [blame] | 319 | deps_files_to_parse = [] |
Ryan Cui | b603c54 | 2011-07-27 16:00:11 -0700 | [diff] [blame] | 320 | if options.deps: |
Ryan Cui | 44360de | 2011-08-22 16:50:20 -0700 | [diff] [blame] | 321 | deps_files_to_parse.append(options.deps) |
| 322 | else: |
| 323 | deps_files_to_parse.append(os.path.join(chromium_src_root, '.DEPS.git')) |
Ryan Cui | b603c54 | 2011-07-27 16:00:11 -0700 | [diff] [blame] | 324 | |
Ryan Cui | d1024a8 | 2011-08-26 17:58:36 -0700 | [diff] [blame] | 325 | internal_deps = os.path.join(repo_root, _CHROMIUM_SRC_INTERNAL, '.DEPS.git') |
| 326 | if os.path.exists(internal_deps): |
| 327 | deps_files_to_parse.append(internal_deps) |
| 328 | |
Ryan Cui | 44360de | 2011-08-22 16:50:20 -0700 | [diff] [blame] | 329 | deps_files_to_parse.append(os.path.join(repo_root, _CHROMIUM_CROS_DEPS)) |
Ryan Cui | b603c54 | 2011-07-27 16:00:11 -0700 | [diff] [blame] | 330 | |
Ryan Cui | 65e1f9a | 2011-09-21 17:06:43 -0700 | [diff] [blame] | 331 | # Prepare source tree for resetting. |
Ryan Cui | 44360de | 2011-08-22 16:50:20 -0700 | [diff] [blame] | 332 | chromium_root = os.path.join(repo_root, _CHROMIUM_ROOT) |
Ryan Cui | b75c303 | 2011-08-10 16:19:39 -0700 | [diff] [blame] | 333 | _CreateCrosSymlink(repo_root) |
Ryan Cui | 44360de | 2011-08-22 16:50:20 -0700 | [diff] [blame] | 334 | |
Ryan Cui | 65e1f9a | 2011-09-21 17:06:43 -0700 | [diff] [blame] | 335 | # Parse DEPS files and store hooks. |
Ryan Cui | 44360de | 2011-08-22 16:50:20 -0700 | [diff] [blame] | 336 | hook_dicts = [] |
| 337 | for deps_file in deps_files_to_parse: |
Ryan Cui | 97b2f30 | 2011-10-24 17:34:05 -0700 | [diff] [blame] | 338 | deps, merged_deps = GetParsedDeps(deps_file) |
Ryan Cui | 446e8e7 | 2011-09-23 18:02:41 -0700 | [diff] [blame] | 339 | _ResetGitCheckout(repo_root, merged_deps) |
Ryan Cui | 44360de | 2011-08-22 16:50:20 -0700 | [diff] [blame] | 340 | hook_dicts.append(deps.get('hooks', {})) |
| 341 | |
Ryan Cui | 65e1f9a | 2011-09-21 17:06:43 -0700 | [diff] [blame] | 342 | # Run hooks after checkout has been reset properly. |
Ryan Cui | 44360de | 2011-08-22 16:50:20 -0700 | [diff] [blame] | 343 | if options.runhooks: |
| 344 | for hooks in hook_dicts: |
| 345 | _RunHooks(chromium_root, hooks) |