Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(889)

Side by Side Diff: gclient.py

Issue 2398493004: Remove SVN and File support from gclient (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tests/gclient_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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:
OLDNEW
« no previous file with comments | « no previous file | tests/gclient_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698