Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 # Files | 7 # Files |
| 8 # .gclient : Current client configuration, written by 'config' command. | 8 # .gclient : Current client configuration, written by 'config' command. |
| 9 # Format is a Python script defining 'solutions', a list whose | 9 # Format is a Python script defining 'solutions', a list whose |
| 10 # entries each are maps binding the strings "name" and "url" | 10 # entries each are maps binding the strings "name" and "url" |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 166 | 166 |
| 167 sub_target_name is an optional parameter if the module name in the other | 167 sub_target_name is an optional parameter if the module name in the other |
| 168 DEPS file is different. E.g., you might want to map src/net to net.""" | 168 DEPS file is different. E.g., you might want to map src/net to net.""" |
| 169 self.module_name = module_name | 169 self.module_name = module_name |
| 170 self.sub_target_name = sub_target_name | 170 self.sub_target_name = sub_target_name |
| 171 | 171 |
| 172 def __str__(self): | 172 def __str__(self): |
| 173 return 'From(%s, %s)' % (repr(self.module_name), | 173 return 'From(%s, %s)' % (repr(self.module_name), |
| 174 repr(self.sub_target_name)) | 174 repr(self.sub_target_name)) |
| 175 | 175 |
| 176 class FileImpl(object): | |
| 177 """Used to implement the File('') syntax which lets you sync a single file | |
| 178 from a SVN repo.""" | |
| 179 | |
| 180 def __init__(self, file_location): | |
| 181 self.file_location = file_location | |
| 182 | |
| 183 def __str__(self): | |
| 184 return 'File("%s")' % self.file_location | |
| 185 | |
| 186 def GetPath(self): | |
| 187 return os.path.split(self.file_location)[0] | |
| 188 | |
| 189 def GetFilename(self): | |
| 190 rev_tokens = self.file_location.split('@') | |
| 191 return os.path.split(rev_tokens[0])[1] | |
| 192 | |
| 193 def GetRevision(self): | |
| 194 rev_tokens = self.file_location.split('@') | |
| 195 if len(rev_tokens) > 1: | |
| 196 return rev_tokens[1] | |
| 197 return None | |
| 198 | |
| 199 class VarImpl(object): | 176 class VarImpl(object): |
| 200 def __init__(self, custom_vars, local_scope): | 177 def __init__(self, custom_vars, local_scope): |
| 201 self._custom_vars = custom_vars | 178 self._custom_vars = custom_vars |
| 202 self._local_scope = local_scope | 179 self._local_scope = local_scope |
| 203 | 180 |
| 204 def Lookup(self, var_name): | 181 def Lookup(self, var_name): |
| 205 """Implements the Var syntax.""" | 182 """Implements the Var syntax.""" |
| 206 if var_name in self._custom_vars: | 183 if var_name in self._custom_vars: |
| 207 return self._custom_vars[var_name] | 184 return self._custom_vars[var_name] |
| 208 elif var_name in self._local_scope.get("vars", {}): | 185 elif var_name in self._local_scope.get("vars", {}): |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 237 self._relative = relative | 214 self._relative = relative |
| 238 # This is a mutable value which has the list of 'target_os' OSes listed in | 215 # This is a mutable value which has the list of 'target_os' OSes listed in |
| 239 # the current deps file. | 216 # the current deps file. |
| 240 self.local_target_os = None | 217 self.local_target_os = None |
| 241 | 218 |
| 242 # These are only set in .gclient and not in DEPS files. | 219 # These are only set in .gclient and not in DEPS files. |
| 243 self._custom_vars = custom_vars or {} | 220 self._custom_vars = custom_vars or {} |
| 244 self._custom_deps = custom_deps or {} | 221 self._custom_deps = custom_deps or {} |
| 245 self._custom_hooks = custom_hooks or [] | 222 self._custom_hooks = custom_hooks or [] |
| 246 | 223 |
| 247 # TODO(iannucci): Remove this when all masters are correctly substituting | |
| 248 # the new blink url. | |
| 249 if (self._custom_vars.get('webkit_trunk', '') == | |
| 250 'svn://svn-mirror.golo.chromium.org/webkit-readonly/trunk'): | |
| 251 new_url = 'svn://svn-mirror.golo.chromium.org/blink/trunk' | |
| 252 print('Overwriting Var("webkit_trunk") with %s' % new_url) | |
| 253 self._custom_vars['webkit_trunk'] = new_url | |
| 254 | |
| 255 # Post process the url to remove trailing slashes. | 224 # Post process the url to remove trailing slashes. |
| 256 if isinstance(self._url, basestring): | 225 if isinstance(self._url, basestring): |
| 257 # urls are sometime incorrectly written as proto://host/path/@rev. Replace | 226 # urls are sometime incorrectly written as proto://host/path/@rev. Replace |
| 258 # it to proto://host/path@rev. | 227 # it to proto://host/path@rev. |
| 259 self._url = self._url.replace('/@', '@') | 228 self._url = self._url.replace('/@', '@') |
| 260 elif not isinstance(self._url, | 229 elif not isinstance(self._url, (self.FromImpl, None.__class__)): |
| 261 (self.FromImpl, self.FileImpl, None.__class__)): | |
| 262 raise gclient_utils.Error( | 230 raise gclient_utils.Error( |
| 263 ('dependency url must be either a string, None, ' | 231 ('dependency url must be either a string, None, ' |
| 264 'File() or From() instead of %s') % self._url.__class__.__name__) | 232 'or From() instead of %s') % self._url.__class__.__name__) |
| 265 # Make any deps_file path platform-appropriate. | 233 # Make any deps_file path platform-appropriate. |
| 266 for sep in ['/', '\\']: | 234 for sep in ['/', '\\']: |
| 267 self._deps_file = self._deps_file.replace(sep, os.sep) | 235 self._deps_file = self._deps_file.replace(sep, os.sep) |
| 268 | 236 |
| 269 @property | 237 @property |
| 270 def deps_file(self): | 238 def deps_file(self): |
| 271 return self._deps_file | 239 return self._deps_file |
| 272 | 240 |
| 273 @property | 241 @property |
| 274 def managed(self): | 242 def managed(self): |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 527 parsed_url = urlparse.urlparse(url) | 495 parsed_url = urlparse.urlparse(url) |
| 528 if (not parsed_url[0] and | 496 if (not parsed_url[0] and |
| 529 not re.match(r'^\w+\@[\w\.-]+\:[\w\/]+', parsed_url[2])): | 497 not re.match(r'^\w+\@[\w\.-]+\:[\w\/]+', parsed_url[2])): |
| 530 # A relative url. Fetch the real base. | 498 # A relative url. Fetch the real base. |
| 531 path = parsed_url[2] | 499 path = parsed_url[2] |
| 532 if not path.startswith('/'): | 500 if not path.startswith('/'): |
| 533 raise gclient_utils.Error( | 501 raise gclient_utils.Error( |
| 534 'relative DEPS entry \'%s\' must begin with a slash' % url) | 502 'relative DEPS entry \'%s\' must begin with a slash' % url) |
| 535 # Create a scm just to query the full url. | 503 # Create a scm just to query the full url. |
| 536 parent_url = self.parent.parsed_url | 504 parent_url = self.parent.parsed_url |
| 537 if isinstance(parent_url, self.FileImpl): | |
| 538 parent_url = parent_url.file_location | |
| 539 scm = gclient_scm.CreateSCM( | 505 scm = gclient_scm.CreateSCM( |
| 540 parent_url, self.root.root_dir, None, self.outbuf) | 506 parent_url, self.root.root_dir, None, self.outbuf) |
| 541 parsed_url = scm.FullUrlForRelativeUrl(url) | 507 parsed_url = scm.FullUrlForRelativeUrl(url) |
| 542 else: | 508 else: |
| 543 parsed_url = url | 509 parsed_url = url |
| 544 logging.info( | 510 logging.info( |
| 545 'Dependency(%s).LateOverride(%s) -> %s' % | 511 'Dependency(%s).LateOverride(%s) -> %s' % |
| 546 (self.name, url, parsed_url)) | 512 (self.name, url, parsed_url)) |
| 547 return parsed_url | 513 return parsed_url |
| 548 | 514 |
| 549 if isinstance(url, self.FileImpl): | |
| 550 logging.info( | |
| 551 'Dependency(%s).LateOverride(%s) -> %s (File)' % | |
| 552 (self.name, url, url)) | |
| 553 return url | |
| 554 | |
| 555 if url is None: | 515 if url is None: |
| 556 logging.info( | 516 logging.info( |
| 557 'Dependency(%s).LateOverride(%s) -> %s' % (self.name, url, url)) | 517 'Dependency(%s).LateOverride(%s) -> %s' % (self.name, url, url)) |
| 558 return url | 518 return url |
| 559 | 519 |
| 560 raise gclient_utils.Error('Unknown url type') | 520 raise gclient_utils.Error('Unknown url type') |
| 561 | 521 |
| 562 @staticmethod | 522 @staticmethod |
| 563 def MergeWithOsDeps(deps, deps_os, target_os_list): | 523 def MergeWithOsDeps(deps, deps_os, target_os_list): |
| 564 """Returns a new "deps" structure that is the deps sent in updated | 524 """Returns a new "deps" structure that is the deps sent in updated |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 635 if use_strict: | 595 if use_strict: |
| 636 logging.info( | 596 logging.info( |
| 637 'ParseDepsFile(%s): Strict Mode Enabled', self.name) | 597 'ParseDepsFile(%s): Strict Mode Enabled', self.name) |
| 638 global_scope = { | 598 global_scope = { |
| 639 '__builtins__': {'None': None}, | 599 '__builtins__': {'None': None}, |
| 640 'Var': var.Lookup, | 600 'Var': var.Lookup, |
| 641 'deps_os': {}, | 601 'deps_os': {}, |
| 642 } | 602 } |
| 643 else: | 603 else: |
| 644 global_scope = { | 604 global_scope = { |
| 645 'File': self.FileImpl, | |
| 646 'From': self.FromImpl, | 605 'From': self.FromImpl, |
| 647 'Var': var.Lookup, | 606 'Var': var.Lookup, |
| 648 'deps_os': {}, | 607 'deps_os': {}, |
| 649 } | 608 } |
| 650 # Eval the content. | 609 # Eval the content. |
| 651 try: | 610 try: |
| 652 exec(deps_content, global_scope, local_scope) | 611 exec(deps_content, global_scope, local_scope) |
| 653 except SyntaxError as e: | 612 except SyntaxError as e: |
| 654 gclient_utils.SyntaxErrorToError(filepath, e) | 613 gclient_utils.SyntaxErrorToError(filepath, e) |
| 655 if use_strict: | 614 if use_strict: |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 835 if not self.should_process: | 794 if not self.should_process: |
| 836 return | 795 return |
| 837 # When running runhooks, there's no need to consult the SCM. | 796 # When running runhooks, there's no need to consult the SCM. |
| 838 # All known hooks are expected to run unconditionally regardless of working | 797 # All known hooks are expected to run unconditionally regardless of working |
| 839 # copy state, so skip the SCM status check. | 798 # copy state, so skip the SCM status check. |
| 840 run_scm = command not in ('runhooks', 'recurse', None) | 799 run_scm = command not in ('runhooks', 'recurse', None) |
| 841 parsed_url = self.LateOverride(self.url) | 800 parsed_url = self.LateOverride(self.url) |
| 842 file_list = [] if not options.nohooks else None | 801 file_list = [] if not options.nohooks else None |
| 843 revision_override = revision_overrides.pop(self.name, None) | 802 revision_override = revision_overrides.pop(self.name, None) |
| 844 if run_scm and parsed_url: | 803 if run_scm and parsed_url: |
| 845 if isinstance(parsed_url, self.FileImpl): | 804 # Create a shallow copy to mutate revision. |
| 846 # Special support for single-file checkout. | 805 options = copy.copy(options) |
| 847 if not command in (None, 'cleanup', 'diff', 'pack', 'status'): | 806 options.revision = revision_override |
| 848 # Sadly, pylint doesn't realize that parsed_url is of FileImpl. | 807 self.maybeGetParentRevision( |
| 849 # pylint: disable=E1103 | 808 command, options, parsed_url, self.parent) |
| 850 options.revision = parsed_url.GetRevision() | 809 self._used_revision = options.revision |
| 851 self._used_scm = gclient_scm.SVNWrapper( | 810 self._used_scm = gclient_scm.CreateSCM( |
| 852 parsed_url.GetPath(), self.root.root_dir, self.name, | 811 parsed_url, self.root.root_dir, self.name, self.outbuf, |
| 853 out_cb=work_queue.out_cb) | 812 out_cb=work_queue.out_cb) |
| 854 self._used_scm.RunCommand('updatesingle', | 813 self._got_revision = self._used_scm.RunCommand(command, options, args, |
| 855 options, args + [parsed_url.GetFilename()], file_list) | 814 file_list) |
| 856 else: | 815 if file_list: |
| 857 # Create a shallow copy to mutate revision. | 816 file_list = [os.path.join(self.name, f.strip()) for f in file_list] |
| 858 options = copy.copy(options) | |
| 859 options.revision = revision_override | |
| 860 self.maybeGetParentRevision( | |
| 861 command, options, parsed_url, self.parent) | |
| 862 self._used_revision = options.revision | |
| 863 self._used_scm = gclient_scm.CreateSCM( | |
| 864 parsed_url, self.root.root_dir, self.name, self.outbuf, | |
| 865 out_cb=work_queue.out_cb) | |
| 866 self._got_revision = self._used_scm.RunCommand(command, options, args, | |
| 867 file_list) | |
| 868 if file_list: | |
| 869 file_list = [os.path.join(self.name, f.strip()) for f in file_list] | |
| 870 | 817 |
| 871 # TODO(phajdan.jr): We should know exactly when the paths are absolute. | 818 # TODO(phajdan.jr): We should know exactly when the paths are absolute. |
| 872 # Convert all absolute paths to relative. | 819 # Convert all absolute paths to relative. |
| 873 for i in range(len(file_list or [])): | 820 for i in range(len(file_list or [])): |
| 874 # It depends on the command being executed (like runhooks vs sync). | 821 # It depends on the command being executed (like runhooks vs sync). |
| 875 if not os.path.isabs(file_list[i]): | 822 if not os.path.isabs(file_list[i]): |
| 876 continue | 823 continue |
| 877 prefix = os.path.commonprefix( | 824 prefix = os.path.commonprefix( |
| 878 [self.root.root_dir.lower(), file_list[i].lower()]) | 825 [self.root.root_dir.lower(), file_list[i].lower()]) |
| 879 file_list[i] = file_list[i][len(prefix):] | 826 file_list[i] = file_list[i][len(prefix):] |
| 880 # Strip any leading path separators. | 827 # Strip any leading path separators. |
| 881 while file_list[i].startswith(('\\', '/')): | 828 while file_list[i].startswith(('\\', '/')): |
| 882 file_list[i] = file_list[i][1:] | 829 file_list[i] = file_list[i][1:] |
| 883 | 830 |
| 884 # Always parse the DEPS file. | 831 # Always parse the DEPS file. |
| 885 self.ParseDepsFile() | 832 self.ParseDepsFile() |
| 886 self._run_is_done(file_list or [], parsed_url) | 833 self._run_is_done(file_list or [], parsed_url) |
| 887 if command in ('update', 'revert') and not options.noprehooks: | 834 if command in ('update', 'revert') and not options.noprehooks: |
| 888 self.RunPreDepsHooks() | 835 self.RunPreDepsHooks() |
| 889 | 836 |
| 890 if self.recursion_limit: | 837 if self.recursion_limit: |
| 891 # Parse the dependencies of this dependency. | 838 # Parse the dependencies of this dependency. |
| 892 for s in self.dependencies: | 839 for s in self.dependencies: |
| 893 work_queue.enqueue(s) | 840 work_queue.enqueue(s) |
| 894 | 841 |
| 895 if command == 'recurse': | 842 if command == 'recurse': |
| 896 if not isinstance(parsed_url, self.FileImpl): | 843 # Skip file only checkout. |
| 897 # Skip file only checkout. | 844 scm = gclient_scm.GetScmName(parsed_url) |
| 898 scm = gclient_scm.GetScmName(parsed_url) | 845 if not options.scm or scm in options.scm: |
| 899 if not options.scm or scm in options.scm: | 846 cwd = os.path.normpath(os.path.join(self.root.root_dir, self.name)) |
| 900 cwd = os.path.normpath(os.path.join(self.root.root_dir, self.name)) | 847 # Pass in the SCM type as an env variable. Make sure we don't put |
| 901 # Pass in the SCM type as an env variable. Make sure we don't put | 848 # unicode strings in the environment. |
| 902 # unicode strings in the environment. | 849 env = os.environ.copy() |
| 903 env = os.environ.copy() | 850 if scm: |
| 904 if scm: | 851 env['GCLIENT_SCM'] = str(scm) |
| 905 env['GCLIENT_SCM'] = str(scm) | 852 if parsed_url: |
| 906 if parsed_url: | 853 env['GCLIENT_URL'] = str(parsed_url) |
| 907 env['GCLIENT_URL'] = str(parsed_url) | 854 env['GCLIENT_DEP_PATH'] = str(self.name) |
| 908 env['GCLIENT_DEP_PATH'] = str(self.name) | 855 if options.prepend_dir and scm == 'git': |
| 909 if options.prepend_dir and scm == 'git': | 856 print_stdout = False |
| 910 print_stdout = False | 857 def filter_fn(line): |
| 911 def filter_fn(line): | 858 """Git-specific path marshaling. It is optimized for git-grep.""" |
| 912 """Git-specific path marshaling. It is optimized for git-grep.""" | |
| 913 | 859 |
| 914 def mod_path(git_pathspec): | 860 def mod_path(git_pathspec): |
| 915 match = re.match('^(\\S+?:)?([^\0]+)$', git_pathspec) | 861 match = re.match('^(\\S+?:)?([^\0]+)$', git_pathspec) |
| 916 modified_path = os.path.join(self.name, match.group(2)) | 862 modified_path = os.path.join(self.name, match.group(2)) |
| 917 branch = match.group(1) or '' | 863 branch = match.group(1) or '' |
| 918 return '%s%s' % (branch, modified_path) | 864 return '%s%s' % (branch, modified_path) |
| 919 | 865 |
| 920 match = re.match('^Binary file ([^\0]+) matches$', line) | 866 match = re.match('^Binary file ([^\0]+) matches$', line) |
| 921 if match: | 867 if match: |
| 922 print('Binary file %s matches\n' % mod_path(match.group(1))) | 868 print('Binary file %s matches\n' % mod_path(match.group(1))) |
| 923 return | 869 return |
| 924 | 870 |
| 925 items = line.split('\0') | 871 items = line.split('\0') |
| 926 if len(items) == 2 and items[1]: | 872 if len(items) == 2 and items[1]: |
| 927 print('%s : %s' % (mod_path(items[0]), items[1])) | 873 print('%s : %s' % (mod_path(items[0]), items[1])) |
| 928 elif len(items) >= 2: | 874 elif len(items) >= 2: |
| 929 # Multiple null bytes or a single trailing null byte indicate | 875 # Multiple null bytes or a single trailing null byte indicate |
| 930 # git is likely displaying filenames only (such as with -l) | 876 # git is likely displaying filenames only (such as with -l) |
| 931 print('\n'.join(mod_path(path) for path in items if path)) | 877 print('\n'.join(mod_path(path) for path in items if path)) |
| 932 else: | 878 else: |
| 933 print(line) | 879 print(line) |
| 934 else: | 880 else: |
| 935 print_stdout = True | 881 print_stdout = True |
| 936 filter_fn = None | 882 filter_fn = None |
| 937 | 883 |
| 938 if parsed_url is None: | 884 if parsed_url is None: |
| 939 print('Skipped omitted dependency %s' % cwd, file=sys.stderr) | 885 print('Skipped omitted dependency %s' % cwd, file=sys.stderr) |
| 940 elif os.path.isdir(cwd): | 886 elif os.path.isdir(cwd): |
| 941 try: | 887 try: |
| 942 gclient_utils.CheckCallAndFilter( | 888 gclient_utils.CheckCallAndFilter( |
| 943 args, cwd=cwd, env=env, print_stdout=print_stdout, | 889 args, cwd=cwd, env=env, print_stdout=print_stdout, |
| 944 filter_fn=filter_fn, | 890 filter_fn=filter_fn, |
| 945 ) | 891 ) |
| 946 except subprocess2.CalledProcessError: | 892 except subprocess2.CalledProcessError: |
| 947 if not options.ignore: | 893 if not options.ignore: |
| 948 raise | 894 raise |
| 949 else: | 895 else: |
| 950 print('Skipped missing %s' % cwd, file=sys.stderr) | 896 print('Skipped missing %s' % cwd, file=sys.stderr) |
| 951 | 897 |
| 952 | 898 |
| 953 @gclient_utils.lockedmethod | 899 @gclient_utils.lockedmethod |
| 954 def _run_is_done(self, file_list, parsed_url): | 900 def _run_is_done(self, file_list, parsed_url): |
| 955 # Both these are kept for hooks that are run as a separate tree traversal. | 901 # Both these are kept for hooks that are run as a separate tree traversal. |
| 956 self._file_list = file_list | 902 self._file_list = file_list |
| 957 self._parsed_url = parsed_url | 903 self._parsed_url = parsed_url |
| 958 self._processed = True | 904 self._processed = True |
| 959 | 905 |
| 960 @staticmethod | 906 @staticmethod |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 978 | 924 |
| 979 RunOnDeps() must have been called before to load the DEPS. | 925 RunOnDeps() must have been called before to load the DEPS. |
| 980 """ | 926 """ |
| 981 result = [] | 927 result = [] |
| 982 if not self.should_process or not self.recursion_limit: | 928 if not self.should_process or not self.recursion_limit: |
| 983 # Don't run the hook when it is above recursion_limit. | 929 # Don't run the hook when it is above recursion_limit. |
| 984 return result | 930 return result |
| 985 # If "--force" was specified, run all hooks regardless of what files have | 931 # If "--force" was specified, run all hooks regardless of what files have |
| 986 # changed. | 932 # changed. |
| 987 if self.deps_hooks: | 933 if self.deps_hooks: |
| 988 # TODO(maruel): If the user is using git or git-svn, then we don't know | 934 # TODO(maruel): If the user is using git, then we don't know |
| 989 # what files have changed so we always run all hooks. It'd be nice to fix | 935 # what files have changed so we always run all hooks. It'd be nice to fix |
| 990 # that. | 936 # that. |
| 991 if (options.force or | 937 if (options.force or |
| 992 isinstance(self.parsed_url, self.FileImpl) or | |
| 993 gclient_scm.GetScmName(self.parsed_url) in ('git', None) or | 938 gclient_scm.GetScmName(self.parsed_url) in ('git', None) or |
| 994 os.path.isdir(os.path.join(self.root.root_dir, self.name, '.git'))): | 939 os.path.isdir(os.path.join(self.root.root_dir, self.name, '.git'))): |
| 995 for hook_dict in self.deps_hooks: | 940 for hook_dict in self.deps_hooks: |
| 996 result.append(self.GetHookAction(hook_dict, [])) | 941 result.append(self.GetHookAction(hook_dict, [])) |
| 997 else: | 942 else: |
| 998 # Run hooks on the basis of whether the files from the gclient operation | 943 # Run hooks on the basis of whether the files from the gclient operation |
| 999 # match each hook's pattern. | 944 # match each hook's pattern. |
| 1000 for hook_dict in self.deps_hooks: | 945 for hook_dict in self.deps_hooks: |
| 1001 pattern = re.compile(hook_dict['pattern']) | 946 pattern = re.compile(hook_dict['pattern']) |
| 1002 matching_file_list = [ | 947 matching_file_list = [ |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1266 is actually checked out in %(checkout_path)s. | 1211 is actually checked out in %(checkout_path)s. |
| 1267 | 1212 |
| 1268 The .gclient file contains: | 1213 The .gclient file contains: |
| 1269 URL: %(expected_url)s (%(expected_scm)s) | 1214 URL: %(expected_url)s (%(expected_scm)s) |
| 1270 Cache mirror: %(mirror_string)s | 1215 Cache mirror: %(mirror_string)s |
| 1271 | 1216 |
| 1272 The local checkout in %(checkout_path)s reports: | 1217 The local checkout in %(checkout_path)s reports: |
| 1273 %(actual_url)s (%(actual_scm)s) | 1218 %(actual_url)s (%(actual_scm)s) |
| 1274 | 1219 |
| 1275 You should ensure that the URL listed in .gclient is correct and either change | 1220 You should ensure that the URL listed in .gclient is correct and either change |
| 1276 it or fix the checkout. If you're managing your own git checkout in | 1221 it or fix the checkout. |
| 1277 %(checkout_path)s but the URL in .gclient is for an svn repository, you probably | |
| 1278 want to set 'managed': False in .gclient. | |
| 1279 ''' % {'checkout_path': os.path.join(self.root_dir, dep.name), | 1222 ''' % {'checkout_path': os.path.join(self.root_dir, dep.name), |
| 1280 'expected_url': dep.url, | 1223 'expected_url': dep.url, |
| 1281 'expected_scm': gclient_scm.GetScmName(dep.url), | 1224 'expected_scm': gclient_scm.GetScmName(dep.url), |
| 1282 'mirror_string' : mirror_string, | 1225 'mirror_string' : mirror_string, |
| 1283 'actual_url': actual_url, | 1226 'actual_url': actual_url, |
| 1284 'actual_scm': gclient_scm.GetScmName(actual_url)}) | 1227 'actual_scm': gclient_scm.GetScmName(actual_url)}) |
| 1285 | 1228 |
| 1286 def SetConfig(self, content): | 1229 def SetConfig(self, content): |
| 1287 assert not self.dependencies | 1230 assert not self.dependencies |
| 1288 config_dict = {} | 1231 config_dict = {} |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1331 raise gclient_utils.Error('Invalid .gclient file. Solution is ' | 1274 raise gclient_utils.Error('Invalid .gclient file. Solution is ' |
| 1332 'incomplete: %s' % s) | 1275 'incomplete: %s' % s) |
| 1333 self.add_dependencies_and_close(deps_to_add, config_dict.get('hooks', [])) | 1276 self.add_dependencies_and_close(deps_to_add, config_dict.get('hooks', [])) |
| 1334 logging.info('SetConfig() done') | 1277 logging.info('SetConfig() done') |
| 1335 | 1278 |
| 1336 def SaveConfig(self): | 1279 def SaveConfig(self): |
| 1337 gclient_utils.FileWrite(os.path.join(self.root_dir, | 1280 gclient_utils.FileWrite(os.path.join(self.root_dir, |
| 1338 self._options.config_filename), | 1281 self._options.config_filename), |
| 1339 self.config_content) | 1282 self.config_content) |
| 1340 | 1283 |
| 1341 def MigrateConfigToGit(self, path, options): | |
| 1342 svn_url_re = re.compile('^(https?://src\.chromium\.org/svn|' | |
| 1343 'svn://svn\.chromium\.org/chrome)/' | |
| 1344 '(trunk|branches/[^/]+)/src') | |
| 1345 old_git_re = re.compile('^(https?://git\.chromium\.org|' | |
| 1346 'ssh://([a-zA-Z_][a-zA-Z0-9_-]*@)?' | |
| 1347 'gerrit\.chromium\.org(:2941[89])?)/' | |
| 1348 'chromium/src\.git') | |
| 1349 # Scan existing .gclient file for obsolete settings. It would be simpler | |
| 1350 # to traverse self.dependencies, but working with the AST allows the code to | |
| 1351 # dump an updated .gclient file that preserves the ordering of the original. | |
| 1352 a = ast.parse(self.config_content, options.config_filename, 'exec') | |
| 1353 modified = False | |
| 1354 solutions = [elem for elem in a.body if 'solutions' in | |
| 1355 [target.id for target in elem.targets]] | |
| 1356 if not solutions: | |
| 1357 return self | |
| 1358 solutions = solutions[-1] | |
| 1359 for solution in solutions.value.elts: | |
| 1360 # Check for obsolete URL's | |
| 1361 url_idx = ast_dict_index(solution, 'url') | |
| 1362 if url_idx == -1: | |
| 1363 continue | |
| 1364 url_val = solution.values[url_idx] | |
| 1365 if type(url_val) is not ast.Str: | |
| 1366 continue | |
| 1367 if (svn_url_re.match(url_val.s.strip())): | |
| 1368 raise gclient_utils.Error( | |
| 1369 """ | |
| 1370 The chromium code repository has migrated completely to git. | |
| 1371 Your SVN-based checkout is now obsolete; you need to create a brand-new | |
| 1372 git checkout by following these instructions: | |
| 1373 | |
| 1374 http://www.chromium.org/developers/how-tos/get-the-code | |
| 1375 """) | |
| 1376 if (old_git_re.match(url_val.s.strip())): | |
| 1377 url_val.s = CHROMIUM_SRC_URL | |
| 1378 modified = True | |
| 1379 | |
| 1380 # Ensure deps_file is set to .DEPS.git. We enforce this here to smooth | |
| 1381 # over switching between pre-git-migration and post-git-migration | |
| 1382 # revisions. | |
| 1383 # - For pre-migration revisions, .DEPS.git must be explicitly set. | |
| 1384 # - For post-migration revisions, .DEPS.git is not present, so gclient | |
| 1385 # will correctly fall back to DEPS. | |
| 1386 if url_val.s == CHROMIUM_SRC_URL: | |
| 1387 deps_file_idx = ast_dict_index(solution, 'deps_file') | |
| 1388 if deps_file_idx != -1: | |
| 1389 continue | |
| 1390 solution.keys.append(ast.Str('deps_file')) | |
| 1391 solution.values.append(ast.Str('.DEPS.git')) | |
| 1392 modified = True | |
| 1393 | |
| 1394 if not modified: | |
| 1395 return self | |
| 1396 | |
| 1397 print( | |
| 1398 """ | |
| 1399 WARNING: gclient detected an obsolete setting in your %s file. The file has | |
| 1400 been automagically updated. The previous version is available at %s.old. | |
| 1401 """ % (options.config_filename, options.config_filename)) | |
| 1402 | |
| 1403 # Replace existing .gclient with the updated version. | |
| 1404 # Return a new GClient instance based on the new content. | |
| 1405 new_content = ast2str(a) | |
| 1406 dot_gclient_fn = os.path.join(path, options.config_filename) | |
| 1407 try: | |
| 1408 os.rename(dot_gclient_fn, dot_gclient_fn + '.old') | |
| 1409 except OSError: | |
| 1410 pass | |
| 1411 with open(dot_gclient_fn, 'w') as fh: | |
| 1412 fh.write(new_content) | |
| 1413 client = GClient(path, options) | |
| 1414 client.SetConfig(new_content) | |
| 1415 return client | |
| 1416 | |
| 1417 @staticmethod | 1284 @staticmethod |
| 1418 def LoadCurrentConfig(options): | 1285 def LoadCurrentConfig(options): |
| 1419 """Searches for and loads a .gclient file relative to the current working | 1286 """Searches for and loads a .gclient file relative to the current working |
| 1420 dir. Returns a GClient object.""" | 1287 dir. Returns a GClient object.""" |
| 1421 if options.spec: | 1288 if options.spec: |
| 1422 client = GClient('.', options) | 1289 client = GClient('.', options) |
| 1423 client.SetConfig(options.spec) | 1290 client.SetConfig(options.spec) |
| 1424 else: | 1291 else: |
| 1425 if options.verbose: | 1292 if options.verbose: |
| 1426 print('Looking for %s starting from %s\n' % ( | 1293 print('Looking for %s starting from %s\n' % ( |
| 1427 options.config_filename, os.getcwd())) | 1294 options.config_filename, os.getcwd())) |
| 1428 path = gclient_utils.FindGclientRoot(os.getcwd(), options.config_filename) | 1295 path = gclient_utils.FindGclientRoot(os.getcwd(), options.config_filename) |
| 1429 if not path: | 1296 if not path: |
| 1430 return None | 1297 return None |
| 1431 client = GClient(path, options) | 1298 client = GClient(path, options) |
| 1432 client.SetConfig(gclient_utils.FileRead( | 1299 client.SetConfig(gclient_utils.FileRead( |
| 1433 os.path.join(path, options.config_filename))) | 1300 os.path.join(path, options.config_filename))) |
| 1434 client = client.MigrateConfigToGit(path, options) | |
| 1435 | 1301 |
| 1436 if (options.revisions and | 1302 if (options.revisions and |
| 1437 len(client.dependencies) > 1 and | 1303 len(client.dependencies) > 1 and |
| 1438 any('@' not in r for r in options.revisions)): | 1304 any('@' not in r for r in options.revisions)): |
| 1439 print( | 1305 print( |
| 1440 ('You must specify the full solution name like --revision %s@%s\n' | 1306 ('You must specify the full solution name like --revision %s@%s\n' |
| 1441 'when you have multiple solutions setup in your .gclient file.\n' | 1307 'when you have multiple solutions setup in your .gclient file.\n' |
| 1442 'Other solutions present are: %s.') % ( | 1308 'Other solutions present are: %s.') % ( |
| 1443 client.dependencies[0].name, | 1309 client.dependencies[0].name, |
| 1444 options.revisions[0], | 1310 options.revisions[0], |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1459 | 1325 |
| 1460 def _SaveEntries(self): | 1326 def _SaveEntries(self): |
| 1461 """Creates a .gclient_entries file to record the list of unique checkouts. | 1327 """Creates a .gclient_entries file to record the list of unique checkouts. |
| 1462 | 1328 |
| 1463 The .gclient_entries file lives in the same directory as .gclient. | 1329 The .gclient_entries file lives in the same directory as .gclient. |
| 1464 """ | 1330 """ |
| 1465 # Sometimes pprint.pformat will use {', sometimes it'll use { ' ... It | 1331 # Sometimes pprint.pformat will use {', sometimes it'll use { ' ... It |
| 1466 # makes testing a bit too fun. | 1332 # makes testing a bit too fun. |
| 1467 result = 'entries = {\n' | 1333 result = 'entries = {\n' |
| 1468 for entry in self.root.subtree(False): | 1334 for entry in self.root.subtree(False): |
| 1469 # Skip over File() dependencies as we can't version them. | 1335 result += ' %s: %s,\n' % (pprint.pformat(entry.name), |
| 1470 if not isinstance(entry.parsed_url, self.FileImpl): | 1336 pprint.pformat(entry.parsed_url)) |
| 1471 result += ' %s: %s,\n' % (pprint.pformat(entry.name), | |
| 1472 pprint.pformat(entry.parsed_url)) | |
| 1473 result += '}\n' | 1337 result += '}\n' |
| 1474 file_path = os.path.join(self.root_dir, self._options.entries_filename) | 1338 file_path = os.path.join(self.root_dir, self._options.entries_filename) |
| 1475 logging.debug(result) | 1339 logging.debug(result) |
| 1476 gclient_utils.FileWrite(file_path, result) | 1340 gclient_utils.FileWrite(file_path, result) |
| 1477 | 1341 |
| 1478 def _ReadEntries(self): | 1342 def _ReadEntries(self): |
| 1479 """Read the .gclient_entries file for the given client. | 1343 """Read the .gclient_entries file for the given client. |
| 1480 | 1344 |
| 1481 Returns: | 1345 Returns: |
| 1482 A sequence of solution names, which will be empty if there is the | 1346 A sequence of solution names, which will be empty if there is the |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1592 e_dir = os.path.join(self.root_dir, entry_fixed) | 1456 e_dir = os.path.join(self.root_dir, entry_fixed) |
| 1593 # Use entry and not entry_fixed there. | 1457 # Use entry and not entry_fixed there. |
| 1594 if (entry not in entries and | 1458 if (entry not in entries and |
| 1595 (not any(path.startswith(entry + '/') for path in entries)) and | 1459 (not any(path.startswith(entry + '/') for path in entries)) and |
| 1596 os.path.exists(e_dir)): | 1460 os.path.exists(e_dir)): |
| 1597 # The entry has been removed from DEPS. | 1461 # The entry has been removed from DEPS. |
| 1598 scm = gclient_scm.CreateSCM( | 1462 scm = gclient_scm.CreateSCM( |
| 1599 prev_url, self.root_dir, entry_fixed, self.outbuf) | 1463 prev_url, self.root_dir, entry_fixed, self.outbuf) |
| 1600 | 1464 |
| 1601 # Check to see if this directory is now part of a higher-up checkout. | 1465 # Check to see if this directory is now part of a higher-up checkout. |
| 1602 # The directory might be part of a git OR svn checkout. | |
| 1603 scm_root = None | 1466 scm_root = None |
| 1604 scm_class = None | 1467 try: |
| 1605 for scm_class in (gclient_scm.scm.GIT, gclient_scm.scm.SVN): | 1468 scm_root = gclient_scm.scm.GIT.GetCheckoutRoot(scm.checkout_path) |
| 1606 try: | 1469 except subprocess2.CalledProcessError: |
| 1607 scm_root = scm_class.GetCheckoutRoot(scm.checkout_path) | 1470 pass |
| 1608 except subprocess2.CalledProcessError: | 1471 if not scm_root: |
| 1609 pass | |
| 1610 if scm_root: | |
| 1611 break | |
| 1612 else: | |
| 1613 logging.warning('Could not find checkout root for %s. Unable to ' | 1472 logging.warning('Could not find checkout root for %s. Unable to ' |
| 1614 'determine whether it is part of a higher-level ' | 1473 'determine whether it is part of a higher-level ' |
| 1615 'checkout, so not removing.' % entry) | 1474 'checkout, so not removing.' % entry) |
| 1616 continue | 1475 continue |
| 1617 | 1476 |
| 1618 # This is to handle the case of third_party/WebKit migrating from | 1477 # This is to handle the case of third_party/WebKit migrating from |
| 1619 # being a DEPS entry to being part of the main project. | 1478 # being a DEPS entry to being part of the main project. |
| 1620 # If the subproject is a Git project, we need to remove its .git | 1479 # If the subproject is a Git project, we need to remove its .git |
| 1621 # folder. Otherwise git operations on that folder will have different | 1480 # folder. Otherwise git operations on that folder will have different |
| 1622 # effects depending on the current working directory. | 1481 # effects depending on the current working directory. |
| 1623 if scm_class == gclient_scm.scm.GIT and ( | 1482 if os.path.abspath(scm_root) == os.path.abspath(e_dir): |
| 1624 os.path.abspath(scm_root) == os.path.abspath(e_dir)): | |
| 1625 e_par_dir = os.path.join(e_dir, os.pardir) | 1483 e_par_dir = os.path.join(e_dir, os.pardir) |
| 1626 if scm_class.IsInsideWorkTree(e_par_dir): | 1484 if gclient_scm.scm.GIT.IsInsideWorkTree(e_par_dir): |
| 1627 par_scm_root = scm_class.GetCheckoutRoot(e_par_dir) | 1485 par_scm_root = gclient_scm.scm.GIT.GetCheckoutRoot(e_par_dir) |
| 1628 # rel_e_dir : relative path of entry w.r.t. its parent repo. | 1486 # rel_e_dir : relative path of entry w.r.t. its parent repo. |
| 1629 rel_e_dir = os.path.relpath(e_dir, par_scm_root) | 1487 rel_e_dir = os.path.relpath(e_dir, par_scm_root) |
| 1630 if scm_class.IsDirectoryVersioned(par_scm_root, rel_e_dir): | 1488 if gclient_scm.scm.GIT.IsDirectoryVersioned( |
| 1489 par_scm_root, rel_e_dir): | |
| 1631 save_dir = scm.GetGitBackupDirPath() | 1490 save_dir = scm.GetGitBackupDirPath() |
| 1632 # Remove any eventual stale backup dir for the same project. | 1491 # Remove any eventual stale backup dir for the same project. |
| 1633 if os.path.exists(save_dir): | 1492 if os.path.exists(save_dir): |
| 1634 gclient_utils.rmtree(save_dir) | 1493 gclient_utils.rmtree(save_dir) |
| 1635 os.rename(os.path.join(e_dir, '.git'), save_dir) | 1494 os.rename(os.path.join(e_dir, '.git'), save_dir) |
| 1636 # When switching between the two states (entry/ is a subproject | 1495 # When switching between the two states (entry/ is a subproject |
| 1637 # -> entry/ is part of the outer project), it is very likely | 1496 # -> entry/ is part of the outer project), it is very likely |
| 1638 # that some files are changed in the checkout, unless we are | 1497 # that some files are changed in the checkout, unless we are |
| 1639 # jumping *exactly* across the commit which changed just DEPS. | 1498 # jumping *exactly* across the commit which changed just DEPS. |
| 1640 # In such case we want to cleanup any eventual stale files | 1499 # In such case we want to cleanup any eventual stale files |
| 1641 # (coming from the old subproject) in order to end up with a | 1500 # (coming from the old subproject) in order to end up with a |
| 1642 # clean checkout. | 1501 # clean checkout. |
| 1643 scm_class.CleanupDir(par_scm_root, rel_e_dir) | 1502 gclient_scm.scm.GIT.CleanupDir(par_scm_root, rel_e_dir) |
| 1644 assert not os.path.exists(os.path.join(e_dir, '.git')) | 1503 assert not os.path.exists(os.path.join(e_dir, '.git')) |
| 1645 print(('\nWARNING: \'%s\' has been moved from DEPS to a higher ' | 1504 print(('\nWARNING: \'%s\' has been moved from DEPS to a higher ' |
| 1646 'level checkout. The git folder containing all the local' | 1505 'level checkout. The git folder containing all the local' |
| 1647 ' branches has been saved to %s.\n' | 1506 ' branches has been saved to %s.\n' |
| 1648 'If you don\'t care about its state you can safely ' | 1507 'If you don\'t care about its state you can safely ' |
| 1649 'remove that folder to free up space.') % | 1508 'remove that folder to free up space.') % |
| 1650 (entry, save_dir)) | 1509 (entry, save_dir)) |
| 1651 continue | 1510 continue |
| 1652 | 1511 |
| 1653 if scm_root in full_entries: | 1512 if scm_root in full_entries: |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 1681 work_queue = gclient_utils.ExecutionQueue( | 1540 work_queue = gclient_utils.ExecutionQueue( |
| 1682 self._options.jobs, None, False, verbose=self._options.verbose) | 1541 self._options.jobs, None, False, verbose=self._options.verbose) |
| 1683 for s in self.dependencies: | 1542 for s in self.dependencies: |
| 1684 work_queue.enqueue(s) | 1543 work_queue.enqueue(s) |
| 1685 work_queue.flush({}, None, [], options=self._options) | 1544 work_queue.flush({}, None, [], options=self._options) |
| 1686 | 1545 |
| 1687 def GetURLAndRev(dep): | 1546 def GetURLAndRev(dep): |
| 1688 """Returns the revision-qualified SCM url for a Dependency.""" | 1547 """Returns the revision-qualified SCM url for a Dependency.""" |
| 1689 if dep.parsed_url is None: | 1548 if dep.parsed_url is None: |
| 1690 return None | 1549 return None |
| 1691 if isinstance(dep.parsed_url, self.FileImpl): | 1550 url, _ = gclient_utils.SplitUrlRevision(dep.parsed_url) |
| 1692 original_url = dep.parsed_url.file_location | |
| 1693 else: | |
| 1694 original_url = dep.parsed_url | |
| 1695 url, _ = gclient_utils.SplitUrlRevision(original_url) | |
| 1696 scm = gclient_scm.CreateSCM( | 1551 scm = gclient_scm.CreateSCM( |
| 1697 original_url, self.root_dir, dep.name, self.outbuf) | 1552 dep.parsed_url, self.root_dir, dep.name, self.outbuf) |
| 1698 if not os.path.isdir(scm.checkout_path): | 1553 if not os.path.isdir(scm.checkout_path): |
| 1699 return None | 1554 return None |
| 1700 return '%s@%s' % (url, scm.revinfo(self._options, [], None)) | 1555 return '%s@%s' % (url, scm.revinfo(self._options, [], None)) |
| 1701 | 1556 |
| 1702 if self._options.snapshot: | 1557 if self._options.snapshot: |
| 1703 new_gclient = '' | 1558 new_gclient = '' |
| 1704 # First level at .gclient | 1559 # First level at .gclient |
| 1705 for d in self.dependencies: | 1560 for d in self.dependencies: |
| 1706 entries = {} | 1561 entries = {} |
| 1707 def GrabDeps(dep): | 1562 def GrabDeps(dep): |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1770 return True | 1625 return True |
| 1771 | 1626 |
| 1772 @property | 1627 @property |
| 1773 def target_os(self): | 1628 def target_os(self): |
| 1774 return self._enforced_os | 1629 return self._enforced_os |
| 1775 | 1630 |
| 1776 | 1631 |
| 1777 #### gclient commands. | 1632 #### gclient commands. |
| 1778 | 1633 |
| 1779 | 1634 |
| 1780 def CMDcleanup(parser, args): | 1635 def CMDcleanup(parser, args): |
|
M-A Ruel
2016/10/05 21:13:33
Let's remove the command.
agable
2016/10/05 22:23:38
Will do in followup CL. (Removing it from gclient_
| |
| 1781 """Cleans up all working copies. | 1636 """DEPRECATED: SVN-only. Cleaned up all working copies. |
| 1782 | 1637 |
| 1783 Mostly svn-specific. Simply runs 'svn cleanup' for each module. | 1638 This is a no-op in Git. |
| 1784 """ | 1639 """ |
| 1785 parser.add_option('--deps', dest='deps_os', metavar='OS_LIST', | 1640 parser.add_option('--deps', dest='deps_os', metavar='OS_LIST', |
| 1786 help='override deps for the specified (comma-separated) ' | 1641 help='override deps for the specified (comma-separated) ' |
| 1787 'platform(s); \'all\' will process all deps_os ' | 1642 'platform(s); \'all\' will process all deps_os ' |
| 1788 'references') | 1643 'references') |
| 1789 (options, args) = parser.parse_args(args) | 1644 (options, args) = parser.parse_args(args) |
| 1790 client = GClient.LoadCurrentConfig(options) | 1645 client = GClient.LoadCurrentConfig(options) |
| 1791 if not client: | 1646 if not client: |
| 1792 raise gclient_utils.Error('client not configured; see \'gclient config\'') | 1647 raise gclient_utils.Error('client not configured; see \'gclient config\'') |
| 1793 if options.verbose: | 1648 if options.verbose: |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1956 return 0 | 1811 return 0 |
| 1957 | 1812 |
| 1958 | 1813 |
| 1959 @subcommand.epilog("""Example: | 1814 @subcommand.epilog("""Example: |
| 1960 gclient pack > patch.txt | 1815 gclient pack > patch.txt |
| 1961 generate simple patch for configured client and dependences | 1816 generate simple patch for configured client and dependences |
| 1962 """) | 1817 """) |
| 1963 def CMDpack(parser, args): | 1818 def CMDpack(parser, args): |
| 1964 """Generates a patch which can be applied at the root of the tree. | 1819 """Generates a patch which can be applied at the root of the tree. |
| 1965 | 1820 |
| 1966 Internally, runs 'svn diff'/'git diff' on each checked out module and | 1821 Internally, runs 'git diff' on each checked out module and |
| 1967 dependencies, and performs minimal postprocessing of the output. The | 1822 dependencies, and performs minimal postprocessing of the output. The |
| 1968 resulting patch is printed to stdout and can be applied to a freshly | 1823 resulting patch is printed to stdout and can be applied to a freshly |
| 1969 checked out tree via 'patch -p0 < patchfile'. | 1824 checked out tree via 'patch -p0 < patchfile'. |
| 1970 """ | 1825 """ |
| 1971 parser.add_option('--deps', dest='deps_os', metavar='OS_LIST', | 1826 parser.add_option('--deps', dest='deps_os', metavar='OS_LIST', |
| 1972 help='override deps for the specified (comma-separated) ' | 1827 help='override deps for the specified (comma-separated) ' |
| 1973 'platform(s); \'all\' will process all deps_os ' | 1828 'platform(s); \'all\' will process all deps_os ' |
| 1974 'references') | 1829 'references') |
| 1975 parser.remove_option('--jobs') | 1830 parser.remove_option('--jobs') |
| 1976 (options, args) = parser.parse_args(args) | 1831 (options, args) = parser.parse_args(args) |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2011 | 1866 |
| 2012 JSON output format: | 1867 JSON output format: |
| 2013 If the --output-json option is specified, the following document structure will | 1868 If the --output-json option is specified, the following document structure will |
| 2014 be emitted to the provided file. 'null' entries may occur for subprojects which | 1869 be emitted to the provided file. 'null' entries may occur for subprojects which |
| 2015 are present in the gclient solution, but were not processed (due to custom_deps, | 1870 are present in the gclient solution, but were not processed (due to custom_deps, |
| 2016 os_deps, etc.) | 1871 os_deps, etc.) |
| 2017 | 1872 |
| 2018 { | 1873 { |
| 2019 "solutions" : { | 1874 "solutions" : { |
| 2020 "<name>": { # <name> is the posix-normalized path to the solution. | 1875 "<name>": { # <name> is the posix-normalized path to the solution. |
| 2021 "revision": [<svn rev int>|<git id hex string>|null], | 1876 "revision": [<git id hex string>|null], |
| 2022 "scm": ["svn"|"git"|null], | 1877 "scm": ["git"|null], |
| 2023 } | 1878 } |
| 2024 } | 1879 } |
| 2025 } | 1880 } |
| 2026 """) | 1881 """) |
| 2027 def CMDsync(parser, args): | 1882 def CMDsync(parser, args): |
| 2028 """Checkout/update all modules.""" | 1883 """Checkout/update all modules.""" |
| 2029 parser.add_option('-f', '--force', action='store_true', | 1884 parser.add_option('-f', '--force', action='store_true', |
| 2030 help='force update even for unchanged modules') | 1885 help='force update even for unchanged modules') |
| 2031 parser.add_option('-n', '--nohooks', action='store_true', | 1886 parser.add_option('-n', '--nohooks', action='store_true', |
| 2032 help='don\'t run hooks after the update is complete') | 1887 help='don\'t run hooks after the update is complete') |
| 2033 parser.add_option('-p', '--noprehooks', action='store_true', | 1888 parser.add_option('-p', '--noprehooks', action='store_true', |
| 2034 help='don\'t run pre-DEPS hooks', default=False) | 1889 help='don\'t run pre-DEPS hooks', default=False) |
| 2035 parser.add_option('-r', '--revision', action='append', | 1890 parser.add_option('-r', '--revision', action='append', |
| 2036 dest='revisions', metavar='REV', default=[], | 1891 dest='revisions', metavar='REV', default=[], |
| 2037 help='Enforces revision/hash for the solutions with the ' | 1892 help='Enforces revision/hash for the solutions with the ' |
| 2038 'format src@rev. The src@ part is optional and can be ' | 1893 'format src@rev. The src@ part is optional and can be ' |
| 2039 'skipped. -r can be used multiple times when .gclient ' | 1894 'skipped. -r can be used multiple times when .gclient ' |
| 2040 'has multiple solutions configured and will work even ' | 1895 'has multiple solutions configured and will work even ' |
| 2041 'if the src@ part is skipped. Note that specifying ' | 1896 'if the src@ part is skipped. Note that specifying ' |
| 2042 '--revision means your safesync_url gets ignored.') | 1897 '--revision means your safesync_url gets ignored.') |
| 2043 parser.add_option('--with_branch_heads', action='store_true', | 1898 parser.add_option('--with_branch_heads', action='store_true', |
| 2044 help='Clone git "branch_heads" refspecs in addition to ' | 1899 help='Clone git "branch_heads" refspecs in addition to ' |
| 2045 'the default refspecs. This adds about 1/2GB to a ' | 1900 'the default refspecs. This adds about 1/2GB to a ' |
| 2046 'full checkout. (git only)') | 1901 'full checkout. (git only)') |
| 2047 parser.add_option('--with_tags', action='store_true', | 1902 parser.add_option('--with_tags', action='store_true', |
| 2048 help='Clone git tags in addition to the default refspecs.') | 1903 help='Clone git tags in addition to the default refspecs.') |
| 2049 parser.add_option('-t', '--transitive', action='store_true', | 1904 parser.add_option('-t', '--transitive', action='store_true', |
|
M-A Ruel
2016/10/05 21:13:33
You can remove it now I think
agable
2016/10/05 22:23:38
Done
| |
| 2050 help='When a revision is specified (in the DEPS file or ' | 1905 help='DEPRECATED') |
| 2051 'with the command-line flag), transitively update ' | |
| 2052 'the dependencies to the date of the given revision. ' | |
| 2053 'Only supported for SVN repositories.') | |
| 2054 parser.add_option('-H', '--head', action='store_true', | 1906 parser.add_option('-H', '--head', action='store_true', |
| 2055 help='skips any safesync_urls specified in ' | 1907 help='skips any safesync_urls specified in ' |
| 2056 'configured solutions and sync to head instead') | 1908 'configured solutions and sync to head instead') |
| 2057 parser.add_option('-D', '--delete_unversioned_trees', action='store_true', | 1909 parser.add_option('-D', '--delete_unversioned_trees', action='store_true', |
| 2058 help='Deletes from the working copy any dependencies that ' | 1910 help='Deletes from the working copy any dependencies that ' |
| 2059 'have been removed since the last sync, as long as ' | 1911 'have been removed since the last sync, as long as ' |
| 2060 'there are no local modifications. When used with ' | 1912 'there are no local modifications. When used with ' |
| 2061 '--force, such dependencies are removed even if they ' | 1913 '--force, such dependencies are removed even if they ' |
| 2062 'have local modifications. When used with --reset, ' | 1914 'have local modifications. When used with --reset, ' |
| 2063 'all untracked directories are removed from the ' | 1915 'all untracked directories are removed from the ' |
| 2064 'working copy, excluding those which are explicitly ' | 1916 'working copy, excluding those which are explicitly ' |
| 2065 'ignored in the repository.') | 1917 'ignored in the repository.') |
| 2066 parser.add_option('-R', '--reset', action='store_true', | 1918 parser.add_option('-R', '--reset', action='store_true', |
| 2067 help='resets any local changes before updating (git only)') | 1919 help='resets any local changes before updating (git only)') |
| 2068 parser.add_option('-M', '--merge', action='store_true', | 1920 parser.add_option('-M', '--merge', action='store_true', |
| 2069 help='merge upstream changes instead of trying to ' | 1921 help='merge upstream changes instead of trying to ' |
| 2070 'fast-forward or rebase') | 1922 'fast-forward or rebase') |
| 2071 parser.add_option('-A', '--auto_rebase', action='store_true', | 1923 parser.add_option('-A', '--auto_rebase', action='store_true', |
| 2072 help='Automatically rebase repositories against local ' | 1924 help='Automatically rebase repositories against local ' |
| 2073 'checkout during update (git only).') | 1925 'checkout during update (git only).') |
| 2074 parser.add_option('--deps', dest='deps_os', metavar='OS_LIST', | 1926 parser.add_option('--deps', dest='deps_os', metavar='OS_LIST', |
| 2075 help='override deps for the specified (comma-separated) ' | 1927 help='override deps for the specified (comma-separated) ' |
| 2076 'platform(s); \'all\' will process all deps_os ' | 1928 'platform(s); \'all\' will process all deps_os ' |
| 2077 'references') | 1929 'references') |
| 2078 parser.add_option('-m', '--manually_grab_svn_rev', action='store_true', | 1930 parser.add_option('-m', '--manually_grab_svn_rev', action='store_true', |
|
M-A Ruel
2016/10/05 21:13:33
same
agable
2016/10/05 22:23:38
Done
| |
| 2079 help='Skip svn up whenever possible by requesting ' | 1931 help='DEPRECATED') |
| 2080 'actual HEAD revision from the repository') | |
| 2081 parser.add_option('--upstream', action='store_true', | 1932 parser.add_option('--upstream', action='store_true', |
| 2082 help='Make repo state match upstream branch.') | 1933 help='Make repo state match upstream branch.') |
| 2083 parser.add_option('--output-json', | 1934 parser.add_option('--output-json', |
| 2084 help='Output a json document to this path containing ' | 1935 help='Output a json document to this path containing ' |
| 2085 'summary information about the sync.') | 1936 'summary information about the sync.') |
| 2086 parser.add_option('--no-history', action='store_true', | 1937 parser.add_option('--no-history', action='store_true', |
| 2087 help='GIT ONLY - Reduces the size/time of the checkout at ' | 1938 help='GIT ONLY - Reduces the size/time of the checkout at ' |
| 2088 'the cost of no history. Requires Git 1.9+') | 1939 'the cost of no history. Requires Git 1.9+') |
| 2089 parser.add_option('--shallow', action='store_true', | 1940 parser.add_option('--shallow', action='store_true', |
| 2090 help='GIT ONLY - Do a shallow clone into the cache dir. ' | 1941 help='GIT ONLY - Do a shallow clone into the cache dir. ' |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2144 raise gclient_utils.Error('client not configured; see \'gclient config\'') | 1995 raise gclient_utils.Error('client not configured; see \'gclient config\'') |
| 2145 if options.verbose: | 1996 if options.verbose: |
| 2146 client.PrintLocationAndContents() | 1997 client.PrintLocationAndContents() |
| 2147 return client.RunOnDeps('diff', args) | 1998 return client.RunOnDeps('diff', args) |
| 2148 | 1999 |
| 2149 | 2000 |
| 2150 def CMDrevert(parser, args): | 2001 def CMDrevert(parser, args): |
| 2151 """Reverts all modifications in every dependencies. | 2002 """Reverts all modifications in every dependencies. |
| 2152 | 2003 |
| 2153 That's the nuclear option to get back to a 'clean' state. It removes anything | 2004 That's the nuclear option to get back to a 'clean' state. It removes anything |
| 2154 that shows up in svn status.""" | 2005 that shows up in git status.""" |
| 2155 parser.add_option('--deps', dest='deps_os', metavar='OS_LIST', | 2006 parser.add_option('--deps', dest='deps_os', metavar='OS_LIST', |
| 2156 help='override deps for the specified (comma-separated) ' | 2007 help='override deps for the specified (comma-separated) ' |
| 2157 'platform(s); \'all\' will process all deps_os ' | 2008 'platform(s); \'all\' will process all deps_os ' |
| 2158 'references') | 2009 'references') |
| 2159 parser.add_option('-n', '--nohooks', action='store_true', | 2010 parser.add_option('-n', '--nohooks', action='store_true', |
| 2160 help='don\'t run hooks after the revert is complete') | 2011 help='don\'t run hooks after the revert is complete') |
| 2161 parser.add_option('-p', '--noprehooks', action='store_true', | 2012 parser.add_option('-p', '--noprehooks', action='store_true', |
| 2162 help='don\'t run pre-DEPS hooks', default=False) | 2013 help='don\'t run pre-DEPS hooks', default=False) |
| 2163 parser.add_option('--upstream', action='store_true', | 2014 parser.add_option('--upstream', action='store_true', |
| 2164 help='Make repo state match upstream branch.') | 2015 help='Make repo state match upstream branch.') |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2196 options.force = True | 2047 options.force = True |
| 2197 options.nohooks = False | 2048 options.nohooks = False |
| 2198 return client.RunOnDeps('runhooks', args) | 2049 return client.RunOnDeps('runhooks', args) |
| 2199 | 2050 |
| 2200 | 2051 |
| 2201 def CMDrevinfo(parser, args): | 2052 def CMDrevinfo(parser, args): |
| 2202 """Outputs revision info mapping for the client and its dependencies. | 2053 """Outputs revision info mapping for the client and its dependencies. |
| 2203 | 2054 |
| 2204 This allows the capture of an overall 'revision' for the source tree that | 2055 This allows the capture of an overall 'revision' for the source tree that |
| 2205 can be used to reproduce the same tree in the future. It is only useful for | 2056 can be used to reproduce the same tree in the future. It is only useful for |
| 2206 'unpinned dependencies', i.e. DEPS/deps references without a svn revision | 2057 'unpinned dependencies', i.e. DEPS/deps references without a git hash. |
| 2207 number or a git hash. A git branch name isn't 'pinned' since the actual | 2058 A git branch name isn't 'pinned' since the actual commit can change. |
| 2208 commit can change. | |
| 2209 """ | 2059 """ |
| 2210 parser.add_option('--deps', dest='deps_os', metavar='OS_LIST', | 2060 parser.add_option('--deps', dest='deps_os', metavar='OS_LIST', |
| 2211 help='override deps for the specified (comma-separated) ' | 2061 help='override deps for the specified (comma-separated) ' |
| 2212 'platform(s); \'all\' will process all deps_os ' | 2062 'platform(s); \'all\' will process all deps_os ' |
| 2213 'references') | 2063 'references') |
| 2214 parser.add_option('-a', '--actual', action='store_true', | 2064 parser.add_option('-a', '--actual', action='store_true', |
| 2215 help='gets the actual checked out revisions instead of the ' | 2065 help='gets the actual checked out revisions instead of the ' |
| 2216 'ones specified in the DEPS and .gclient files') | 2066 'ones specified in the DEPS and .gclient files') |
| 2217 parser.add_option('-s', '--snapshot', action='store_true', | 2067 parser.add_option('-s', '--snapshot', action='store_true', |
| 2218 help='creates a snapshot .gclient file of the current ' | 2068 help='creates a snapshot .gclient file of the current ' |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2264 | 2114 |
| 2265 def __init__(self, **kwargs): | 2115 def __init__(self, **kwargs): |
| 2266 optparse.OptionParser.__init__( | 2116 optparse.OptionParser.__init__( |
| 2267 self, version='%prog ' + __version__, **kwargs) | 2117 self, version='%prog ' + __version__, **kwargs) |
| 2268 | 2118 |
| 2269 # Some arm boards have issues with parallel sync. | 2119 # Some arm boards have issues with parallel sync. |
| 2270 if platform.machine().startswith('arm'): | 2120 if platform.machine().startswith('arm'): |
| 2271 jobs = 1 | 2121 jobs = 1 |
| 2272 else: | 2122 else: |
| 2273 jobs = max(8, gclient_utils.NumLocalCpus()) | 2123 jobs = max(8, gclient_utils.NumLocalCpus()) |
| 2274 # cmp: 2013/06/19 | |
| 2275 # Temporary workaround to lower bot-load on SVN server. | |
| 2276 # Bypassed if a bot_update flag is detected. | |
| 2277 if (os.environ.get('CHROME_HEADLESS') == '1' and | |
| 2278 not os.path.exists('update.flag')): | |
| 2279 jobs = 1 | |
| 2280 | 2124 |
| 2281 self.add_option( | 2125 self.add_option( |
| 2282 '-j', '--jobs', default=jobs, type='int', | 2126 '-j', '--jobs', default=jobs, type='int', |
| 2283 help='Specify how many SCM commands can run in parallel; defaults to ' | 2127 help='Specify how many SCM commands can run in parallel; defaults to ' |
| 2284 '%default on this machine') | 2128 '%default on this machine') |
| 2285 self.add_option( | 2129 self.add_option( |
| 2286 '-v', '--verbose', action='count', default=0, | 2130 '-v', '--verbose', action='count', default=0, |
| 2287 help='Produces additional output for diagnostics. Can be used up to ' | 2131 help='Produces additional output for diagnostics. Can be used up to ' |
| 2288 'three times for more logging info.') | 2132 'three times for more logging info.') |
| 2289 self.add_option( | 2133 self.add_option( |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2374 | 2218 |
| 2375 | 2219 |
| 2376 if '__main__' == __name__: | 2220 if '__main__' == __name__: |
| 2377 try: | 2221 try: |
| 2378 sys.exit(main(sys.argv[1:])) | 2222 sys.exit(main(sys.argv[1:])) |
| 2379 except KeyboardInterrupt: | 2223 except KeyboardInterrupt: |
| 2380 sys.stderr.write('interrupted\n') | 2224 sys.stderr.write('interrupted\n') |
| 2381 sys.exit(1) | 2225 sys.exit(1) |
| 2382 | 2226 |
| 2383 # vim: ts=2:sw=2:tw=80:et: | 2227 # vim: ts=2:sw=2:tw=80:et: |
| OLD | NEW |