OLD | NEW |
---|---|
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2010 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 """Meta checkout manager supporting both Subversion and GIT. | 6 """Meta checkout manager supporting both Subversion and GIT. |
7 | 7 |
8 Files | 8 Files |
9 .gclient : Current client configuration, written by 'config' command. | 9 .gclient : Current client configuration, written by 'config' command. |
10 Format is a Python script defining 'solutions', a list whose | 10 Format is a Python script defining 'solutions', a list whose |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
47 { "pattern": "\\.(gif|jpe?g|pr0n|png)$", | 47 { "pattern": "\\.(gif|jpe?g|pr0n|png)$", |
48 "action": ["python", "image_indexer.py", "--all"]}, | 48 "action": ["python", "image_indexer.py", "--all"]}, |
49 ] | 49 ] |
50 """ | 50 """ |
51 | 51 |
52 __version__ = "0.5" | 52 __version__ = "0.5" |
53 | 53 |
54 import logging | 54 import logging |
55 import optparse | 55 import optparse |
56 import os | 56 import os |
57 import posixpath | |
57 import pprint | 58 import pprint |
58 import re | 59 import re |
59 import subprocess | 60 import subprocess |
60 import sys | 61 import sys |
61 import urlparse | 62 import urlparse |
62 import urllib | 63 import urllib |
63 | 64 |
64 import breakpad | 65 import breakpad |
65 | 66 |
66 import gclient_scm | 67 import gclient_scm |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
158 # dependency, i.e. its DEPS wasn't read. | 159 # dependency, i.e. its DEPS wasn't read. |
159 self.deps_parsed = False | 160 self.deps_parsed = False |
160 # A direct reference is dependency that is referenced by a deps, deps_os or | 161 # A direct reference is dependency that is referenced by a deps, deps_os or |
161 # solution. A indirect one is one that was loaded with From() or that | 162 # solution. A indirect one is one that was loaded with From() or that |
162 # exceeded recursion limit. | 163 # exceeded recursion limit. |
163 self.direct_reference = False | 164 self.direct_reference = False |
164 # This dependency has been processed, i.e. checked out | 165 # This dependency has been processed, i.e. checked out |
165 self.processed = False | 166 self.processed = False |
166 # This dependency had its hook run | 167 # This dependency had its hook run |
167 self.hooks_ran = False | 168 self.hooks_ran = False |
169 # Required dependencies to run before running this one: | |
170 self.requirements = [] | |
171 if self.parent and self.parent.name: | |
172 self.requirements.append(self.parent.name) | |
173 if isinstance(self.url, self.FromImpl): | |
174 self.requirements.append(self.url.module_name) | |
168 | 175 |
169 # Sanity checks | 176 # Sanity checks |
170 if not self.name and self.parent: | 177 if not self.name and self.parent: |
171 raise gclient_utils.Error('Dependency without name') | 178 raise gclient_utils.Error('Dependency without name') |
172 if not isinstance(self.url, | 179 if not isinstance(self.url, |
173 (basestring, self.FromImpl, self.FileImpl, None.__class__)): | 180 (basestring, self.FromImpl, self.FileImpl, None.__class__)): |
174 raise gclient_utils.Error('dependency url must be either a string, None, ' | 181 raise gclient_utils.Error('dependency url must be either a string, None, ' |
175 'File() or From() instead of %s' % | 182 'File() or From() instead of %s' % |
176 self.url.__class__.__name__) | 183 self.url.__class__.__name__) |
177 if '/' in self.deps_file or '\\' in self.deps_file: | 184 if '/' in self.deps_file or '\\' in self.deps_file: |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
355 # itself, .i.e. this code is called one time for the .gclient. This is not | 362 # itself, .i.e. this code is called one time for the .gclient. This is not |
356 # conceptually correct but it simplifies code. | 363 # conceptually correct but it simplifies code. |
357 pm._total = len(self.tree(False)) + 1 | 364 pm._total = len(self.tree(False)) + 1 |
358 pm.update() | 365 pm.update() |
359 if self.recursion_limit(): | 366 if self.recursion_limit(): |
360 # Then we can parse the DEPS file. | 367 # Then we can parse the DEPS file. |
361 self.ParseDepsFile(True) | 368 self.ParseDepsFile(True) |
362 if pm: | 369 if pm: |
363 pm._total = len(self.tree(False)) + 1 | 370 pm._total = len(self.tree(False)) + 1 |
364 pm.update(0) | 371 pm.update(0) |
372 # Adjust the implicit dependency requirement; e.g. if a DEPS file contains | |
373 # both src/foo and src/foo/bar, src/foo/bar is implicitly dependent of | |
374 # src/foo. Yes, it's O(n^2)... | |
bradn
2010/08/10 20:21:02
Wait so, do I understand correctly that a sort won
M-A Ruel
2010/08/10 20:28:45
Yes. In pagespeed, they have something like that:
| |
375 for s in self.dependencies: | |
376 for s2 in self.dependencies: | |
377 if s is s2: | |
378 continue | |
379 if s.name.startswith(posixpath.join(s2.name, '')): | |
380 s.requirements.append(s2.name) | |
381 | |
365 # Parse the dependencies of this dependency. | 382 # Parse the dependencies of this dependency. |
366 for s in self.dependencies: | 383 for s in self.dependencies: |
367 # TODO(maruel): All these can run concurrently! No need for threads, | 384 # TODO(maruel): All these can run concurrently! No need for threads, |
368 # just buffer stdout&stderr on pipes and flush as they complete. | 385 # just buffer stdout&stderr on pipes and flush as they complete. |
369 # Watch out for stdin. | 386 # Watch out for stdin. |
370 s.RunCommandRecursively(options, revision_overrides, command, args, pm) | 387 s.RunCommandRecursively(options, revision_overrides, command, args, pm) |
371 | 388 |
372 def RunHooksRecursively(self, options): | 389 def RunHooksRecursively(self, options): |
373 """Evaluates all hooks, running actions as needed. RunCommandRecursively() | 390 """Evaluates all hooks, running actions as needed. RunCommandRecursively() |
374 must have been called before to load the DEPS.""" | 391 must have been called before to load the DEPS.""" |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
469 def file_list(self): | 486 def file_list(self): |
470 result = self._file_list[:] | 487 result = self._file_list[:] |
471 for d in self.dependencies: | 488 for d in self.dependencies: |
472 result.extend(d.file_list()) | 489 result.extend(d.file_list()) |
473 return result | 490 return result |
474 | 491 |
475 def __str__(self): | 492 def __str__(self): |
476 out = [] | 493 out = [] |
477 for i in ('name', 'url', 'parsed_url', 'safesync_url', 'custom_deps', | 494 for i in ('name', 'url', 'parsed_url', 'safesync_url', 'custom_deps', |
478 'custom_vars', 'deps_hooks', '_file_list', 'processed', | 495 'custom_vars', 'deps_hooks', '_file_list', 'processed', |
479 'hooks_ran', 'deps_parsed'): | 496 'hooks_ran', 'deps_parsed', 'requirements'): |
480 # 'deps_file' | 497 # 'deps_file' |
481 if self.__dict__[i]: | 498 if self.__dict__[i]: |
482 out.append('%s: %s' % (i, self.__dict__[i])) | 499 out.append('%s: %s' % (i, self.__dict__[i])) |
483 | 500 |
484 for d in self.dependencies: | 501 for d in self.dependencies: |
485 out.extend([' ' + x for x in str(d).splitlines()]) | 502 out.extend([' ' + x for x in str(d).splitlines()]) |
486 out.append('') | 503 out.append('') |
487 return '\n'.join(out) | 504 return '\n'.join(out) |
488 | 505 |
489 def __repr__(self): | 506 def __repr__(self): |
(...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1194 return CMDhelp(parser, argv) | 1211 return CMDhelp(parser, argv) |
1195 except gclient_utils.Error, e: | 1212 except gclient_utils.Error, e: |
1196 print >> sys.stderr, 'Error: %s' % str(e) | 1213 print >> sys.stderr, 'Error: %s' % str(e) |
1197 return 1 | 1214 return 1 |
1198 | 1215 |
1199 | 1216 |
1200 if '__main__' == __name__: | 1217 if '__main__' == __name__: |
1201 sys.exit(Main(sys.argv[1:])) | 1218 sys.exit(Main(sys.argv[1:])) |
1202 | 1219 |
1203 # vim: ts=2:sw=2:tw=80:et: | 1220 # vim: ts=2:sw=2:tw=80:et: |
OLD | NEW |