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

Side by Side Diff: gclient_scm.py

Issue 385007: Run pychecker over most scripts in depot_tools. Catched a few bugs. (Closed)
Patch Set: . Created 11 years, 1 month 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
OLDNEW
1 # Copyright 2009 Google Inc. All Rights Reserved. 1 # Copyright 2009 Google Inc. All Rights Reserved.
2 # 2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); 3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License. 4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at 5 # You may obtain a copy of the License at
6 # 6 #
7 # http://www.apache.org/licenses/LICENSE-2.0 7 # http://www.apache.org/licenses/LICENSE-2.0
8 # 8 #
9 # Unless required by applicable law or agreed to in writing, software 9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, 10 # distributed under the License is distributed on an "AS IS" BASIS,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 command, self.scm_name)) 89 command, self.scm_name))
90 90
91 return getattr(self, command)(options, args, file_list) 91 return getattr(self, command)(options, args, file_list)
92 92
93 93
94 class GitWrapper(SCMWrapper): 94 class GitWrapper(SCMWrapper):
95 """Wrapper for Git""" 95 """Wrapper for Git"""
96 96
97 def cleanup(self, options, args, file_list): 97 def cleanup(self, options, args, file_list):
98 """Cleanup working copy.""" 98 """Cleanup working copy."""
99 __pychecker__ = 'unusednames=args,file_list,options'
99 self._RunGit(['prune'], redirect_stdout=False) 100 self._RunGit(['prune'], redirect_stdout=False)
100 self._RunGit(['fsck'], redirect_stdout=False) 101 self._RunGit(['fsck'], redirect_stdout=False)
101 self._RunGit(['gc'], redirect_stdout=False) 102 self._RunGit(['gc'], redirect_stdout=False)
102 103
103 def diff(self, options, args, file_list): 104 def diff(self, options, args, file_list):
104 # NOTE: This function does not currently modify file_list. 105 __pychecker__ = 'unusednames=args,file_list,options'
105 merge_base = self._RunGit(['merge-base', 'HEAD', 'origin']) 106 merge_base = self._RunGit(['merge-base', 'HEAD', 'origin'])
106 self._RunGit(['diff', merge_base], redirect_stdout=False) 107 self._RunGit(['diff', merge_base], redirect_stdout=False)
107 108
108 def export(self, options, args, file_list): 109 def export(self, options, args, file_list):
110 __pychecker__ = 'unusednames=file_list,options'
109 assert len(args) == 1 111 assert len(args) == 1
110 export_path = os.path.abspath(os.path.join(args[0], self.relpath)) 112 export_path = os.path.abspath(os.path.join(args[0], self.relpath))
111 if not os.path.exists(export_path): 113 if not os.path.exists(export_path):
112 os.makedirs(export_path) 114 os.makedirs(export_path)
113 self._RunGit(['checkout-index', '-a', '--prefix=%s/' % export_path], 115 self._RunGit(['checkout-index', '-a', '--prefix=%s/' % export_path],
114 redirect_stdout=False) 116 redirect_stdout=False)
115 117
116 def update(self, options, args, file_list): 118 def update(self, options, args, file_list):
117 """Runs git to update or transparently checkout the working copy. 119 """Runs git to update or transparently checkout the working copy.
118 120
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 files = self._RunGit(['diff', new_base, '--name-only']).split() 162 files = self._RunGit(['diff', new_base, '--name-only']).split()
161 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) 163 file_list.extend([os.path.join(self.checkout_path, f) for f in files])
162 self._RunGit(['rebase', '-v', new_base], redirect_stdout=False) 164 self._RunGit(['rebase', '-v', new_base], redirect_stdout=False)
163 print "Checked out revision %s." % self.revinfo(options, (), None) 165 print "Checked out revision %s." % self.revinfo(options, (), None)
164 166
165 def revert(self, options, args, file_list): 167 def revert(self, options, args, file_list):
166 """Reverts local modifications. 168 """Reverts local modifications.
167 169
168 All reverted files will be appended to file_list. 170 All reverted files will be appended to file_list.
169 """ 171 """
172 __pychecker__ = 'unusednames=args'
170 path = os.path.join(self._root_dir, self.relpath) 173 path = os.path.join(self._root_dir, self.relpath)
171 if not os.path.isdir(path): 174 if not os.path.isdir(path):
172 # revert won't work if the directory doesn't exist. It needs to 175 # revert won't work if the directory doesn't exist. It needs to
173 # checkout instead. 176 # checkout instead.
174 print("\n_____ %s is missing, synching instead" % self.relpath) 177 print("\n_____ %s is missing, synching instead" % self.relpath)
175 # Don't reuse the args. 178 # Don't reuse the args.
176 return self.update(options, [], file_list) 179 return self.update(options, [], file_list)
177 merge_base = self._RunGit(['merge-base', 'HEAD', 'origin']) 180 merge_base = self._RunGit(['merge-base', 'HEAD', 'origin'])
178 files = self._RunGit(['diff', merge_base, '--name-only']).split() 181 files = self._RunGit(['diff', merge_base, '--name-only']).split()
179 self._RunGit(['reset', '--hard', merge_base], redirect_stdout=False) 182 self._RunGit(['reset', '--hard', merge_base], redirect_stdout=False)
180 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) 183 file_list.extend([os.path.join(self.checkout_path, f) for f in files])
181 184
182 def revinfo(self, options, args, file_list): 185 def revinfo(self, options, args, file_list):
183 """Display revision""" 186 """Display revision"""
187 __pychecker__ = 'unusednames=args,file_list,options'
184 return self._RunGit(['rev-parse', 'HEAD']) 188 return self._RunGit(['rev-parse', 'HEAD'])
185 189
186 def runhooks(self, options, args, file_list): 190 def runhooks(self, options, args, file_list):
187 self.status(options, args, file_list) 191 self.status(options, args, file_list)
188 192
189 def status(self, options, args, file_list): 193 def status(self, options, args, file_list):
190 """Display status information.""" 194 """Display status information."""
195 __pychecker__ = 'unusednames=args,options'
191 if not os.path.isdir(self.checkout_path): 196 if not os.path.isdir(self.checkout_path):
192 print('\n________ couldn\'t run status in %s:\nThe directory ' 197 print('\n________ couldn\'t run status in %s:\nThe directory '
193 'does not exist.' % checkout_path) 198 'does not exist.' % self.checkout_path)
194 else: 199 else:
195 merge_base = self._RunGit(['merge-base', 'HEAD', 'origin']) 200 merge_base = self._RunGit(['merge-base', 'HEAD', 'origin'])
196 self._RunGit(['diff', '--name-status', merge_base], redirect_stdout=False) 201 self._RunGit(['diff', '--name-status', merge_base], redirect_stdout=False)
197 files = self._RunGit(['diff', '--name-only', merge_base]).split() 202 files = self._RunGit(['diff', '--name-only', merge_base]).split()
198 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) 203 file_list.extend([os.path.join(self.checkout_path, f) for f in files])
199 204
200 def _RunGit(self, args, cwd=None, checkrc=True, redirect_stdout=True): 205 def _RunGit(self, args, cwd=None, checkrc=True, redirect_stdout=True):
201 stdout=None 206 stdout=None
202 if redirect_stdout: 207 if redirect_stdout:
203 stdout=subprocess.PIPE 208 stdout=subprocess.PIPE
204 if cwd == None: 209 if cwd == None:
205 cwd = self.checkout_path 210 cwd = self.checkout_path
206 cmd = ['git'] 211 cmd = ['git']
207 cmd.extend(args) 212 cmd.extend(args)
208 sp = subprocess.Popen(cmd, cwd=cwd, stdout=stdout) 213 sp = subprocess.Popen(cmd, cwd=cwd, stdout=stdout)
209 if checkrc and sp.returncode: 214 if checkrc and sp.returncode:
210 raise gclient_utils.Error('git command %s returned %d' % 215 raise gclient_utils.Error('git command %s returned %d' %
211 (args[0], sp.returncode)) 216 (args[0], sp.returncode))
212 output = sp.communicate()[0] 217 output = sp.communicate()[0]
213 if output != None: 218 if output != None:
214 return output.strip() 219 return output.strip()
215 220
216 221
217 class SVNWrapper(SCMWrapper): 222 class SVNWrapper(SCMWrapper):
218 """ Wrapper for SVN """ 223 """ Wrapper for SVN """
219 224
220 def cleanup(self, options, args, file_list): 225 def cleanup(self, options, args, file_list):
221 """Cleanup working copy.""" 226 """Cleanup working copy."""
227 __pychecker__ = 'unusednames=file_list,options'
222 command = ['cleanup'] 228 command = ['cleanup']
223 command.extend(args) 229 command.extend(args)
224 RunSVN(command, os.path.join(self._root_dir, self.relpath)) 230 RunSVN(command, os.path.join(self._root_dir, self.relpath))
225 231
226 def diff(self, options, args, file_list): 232 def diff(self, options, args, file_list):
227 # NOTE: This function does not currently modify file_list. 233 # NOTE: This function does not currently modify file_list.
234 __pychecker__ = 'unusednames=file_list,options'
228 command = ['diff'] 235 command = ['diff']
229 command.extend(args) 236 command.extend(args)
230 RunSVN(command, os.path.join(self._root_dir, self.relpath)) 237 RunSVN(command, os.path.join(self._root_dir, self.relpath))
231 238
232 def export(self, options, args, file_list): 239 def export(self, options, args, file_list):
240 __pychecker__ = 'unusednames=file_list,options'
233 assert len(args) == 1 241 assert len(args) == 1
234 export_path = os.path.abspath(os.path.join(args[0], self.relpath)) 242 export_path = os.path.abspath(os.path.join(args[0], self.relpath))
235 try: 243 try:
236 os.makedirs(export_path) 244 os.makedirs(export_path)
237 except OSError: 245 except OSError:
238 pass 246 pass
239 assert os.path.exists(export_path) 247 assert os.path.exists(export_path)
240 command = ['export', '--force', '.'] 248 command = ['export', '--force', '.']
241 command.append(export_path) 249 command.append(export_path)
242 RunSVN(command, os.path.join(self._root_dir, self.relpath)) 250 RunSVN(command, os.path.join(self._root_dir, self.relpath))
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 if revision: 362 if revision:
355 command.extend(['--revision', str(revision)]) 363 command.extend(['--revision', str(revision)])
356 RunSVNAndGetFileList(options, command, self._root_dir, file_list) 364 RunSVNAndGetFileList(options, command, self._root_dir, file_list)
357 365
358 def revert(self, options, args, file_list): 366 def revert(self, options, args, file_list):
359 """Reverts local modifications. Subversion specific. 367 """Reverts local modifications. Subversion specific.
360 368
361 All reverted files will be appended to file_list, even if Subversion 369 All reverted files will be appended to file_list, even if Subversion
362 doesn't know about them. 370 doesn't know about them.
363 """ 371 """
372 __pychecker__ = 'unusednames=args'
364 path = os.path.join(self._root_dir, self.relpath) 373 path = os.path.join(self._root_dir, self.relpath)
365 if not os.path.isdir(path): 374 if not os.path.isdir(path):
366 # svn revert won't work if the directory doesn't exist. It needs to 375 # svn revert won't work if the directory doesn't exist. It needs to
367 # checkout instead. 376 # checkout instead.
368 print("\n_____ %s is missing, synching instead" % self.relpath) 377 print("\n_____ %s is missing, synching instead" % self.relpath)
369 # Don't reuse the args. 378 # Don't reuse the args.
370 return self.update(options, [], file_list) 379 return self.update(options, [], file_list)
371 380
372 for file in CaptureSVNStatus(path): 381 for file_status in CaptureSVNStatus(path):
373 file_path = os.path.join(path, file[1]) 382 file_path = os.path.join(path, file_status[1])
374 if file[0][0] == 'X': 383 if file_status[0][0] == 'X':
375 # Ignore externals. 384 # Ignore externals.
376 logging.info('Ignoring external %s' % file_path) 385 logging.info('Ignoring external %s' % file_path)
377 continue 386 continue
378 387
379 if logging.getLogger().isEnabledFor(logging.INFO): 388 if logging.getLogger().isEnabledFor(logging.INFO):
380 logging.info('%s%s' % (file[0], file[1])) 389 logging.info('%s%s' % (file[0], file[1]))
381 else: 390 else:
382 print(file_path) 391 print(file_path)
383 if file[0].isspace(): 392 if file_status[0].isspace():
384 logging.error('No idea what is the status of %s.\n' 393 logging.error('No idea what is the status of %s.\n'
385 'You just found a bug in gclient, please ping ' 394 'You just found a bug in gclient, please ping '
386 'maruel@chromium.org ASAP!' % file_path) 395 'maruel@chromium.org ASAP!' % file_path)
387 # svn revert is really stupid. It fails on inconsistent line-endings, 396 # svn revert is really stupid. It fails on inconsistent line-endings,
388 # on switched directories, etc. So take no chance and delete everything! 397 # on switched directories, etc. So take no chance and delete everything!
389 try: 398 try:
390 if not os.path.exists(file_path): 399 if not os.path.exists(file_path):
391 pass 400 pass
392 elif os.path.isfile(file_path): 401 elif os.path.isfile(file_path):
393 logging.info('os.remove(%s)' % file_path) 402 logging.info('os.remove(%s)' % file_path)
(...skipping 12 matching lines...) Expand all
406 # "svn up --revision BASE" achieve the same effect. 415 # "svn up --revision BASE" achieve the same effect.
407 RunSVNAndGetFileList(options, ['update', '--revision', 'BASE'], path, 416 RunSVNAndGetFileList(options, ['update', '--revision', 'BASE'], path,
408 file_list) 417 file_list)
409 except OSError, e: 418 except OSError, e:
410 # Maybe the directory disapeared meanwhile. We don't want it to throw an 419 # Maybe the directory disapeared meanwhile. We don't want it to throw an
411 # exception. 420 # exception.
412 logging.error('Failed to update:\n%s' % str(e)) 421 logging.error('Failed to update:\n%s' % str(e))
413 422
414 def revinfo(self, options, args, file_list): 423 def revinfo(self, options, args, file_list):
415 """Display revision""" 424 """Display revision"""
425 __pychecker__ = 'unusednames=args,file_list,options'
416 return CaptureSVNHeadRevision(self.url) 426 return CaptureSVNHeadRevision(self.url)
417 427
418 def runhooks(self, options, args, file_list): 428 def runhooks(self, options, args, file_list):
419 self.status(options, args, file_list) 429 self.status(options, args, file_list)
420 430
421 def status(self, options, args, file_list): 431 def status(self, options, args, file_list):
422 """Display status information.""" 432 """Display status information."""
423 path = os.path.join(self._root_dir, self.relpath) 433 path = os.path.join(self._root_dir, self.relpath)
424 command = ['status'] 434 command = ['status']
425 command.extend(args) 435 command.extend(args)
426 if not os.path.isdir(path): 436 if not os.path.isdir(path):
427 # svn status won't work if the directory doesn't exist. 437 # svn status won't work if the directory doesn't exist.
428 print("\n________ couldn't run \'%s\' in \'%s\':\nThe directory " 438 print("\n________ couldn't run \'%s\' in \'%s\':\nThe directory "
429 "does not exist." 439 "does not exist."
430 % (' '.join(command), path)) 440 % (' '.join(command), path))
431 # There's no file list to retrieve. 441 # There's no file list to retrieve.
432 else: 442 else:
433 RunSVNAndGetFileList(options, command, path, file_list) 443 RunSVNAndGetFileList(options, command, path, file_list)
434 444
435 def pack(self, options, args, file_list): 445 def pack(self, options, args, file_list):
436 """Generates a patch file which can be applied to the root of the 446 """Generates a patch file which can be applied to the root of the
437 repository.""" 447 repository."""
448 __pychecker__ = 'unusednames=file_list,options'
438 path = os.path.join(self._root_dir, self.relpath) 449 path = os.path.join(self._root_dir, self.relpath)
439 command = ['diff'] 450 command = ['diff']
440 command.extend(args) 451 command.extend(args)
441 # Simple class which tracks which file is being diffed and 452 # Simple class which tracks which file is being diffed and
442 # replaces instances of its file name in the original and 453 # replaces instances of its file name in the original and
443 # working copy lines of the svn diff output. 454 # working copy lines of the svn diff output.
444 class DiffFilterer(object): 455 class DiffFilterer(object):
445 index_string = "Index: " 456 index_string = "Index: "
446 original_prefix = "--- " 457 original_prefix = "--- "
447 working_prefix = "+++ " 458 working_prefix = "+++ "
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 'normal': ' ', 761 'normal': ' ',
751 'obstructed': '~', 762 'obstructed': '~',
752 'replaced': 'R', 763 'replaced': 'R',
753 'unversioned': '?', 764 'unversioned': '?',
754 } 765 }
755 dom = gclient_utils.ParseXML(CaptureSVN(command)) 766 dom = gclient_utils.ParseXML(CaptureSVN(command))
756 results = [] 767 results = []
757 if dom: 768 if dom:
758 # /status/target/entry/(wc-status|commit|author|date) 769 # /status/target/entry/(wc-status|commit|author|date)
759 for target in dom.getElementsByTagName('target'): 770 for target in dom.getElementsByTagName('target'):
760 base_path = target.getAttribute('path')
761 for entry in target.getElementsByTagName('entry'): 771 for entry in target.getElementsByTagName('entry'):
762 file = entry.getAttribute('path') 772 file_path = entry.getAttribute('path')
763 wc_status = entry.getElementsByTagName('wc-status') 773 wc_status = entry.getElementsByTagName('wc-status')
764 assert len(wc_status) == 1 774 assert len(wc_status) == 1
765 # Emulate svn 1.5 status ouput... 775 # Emulate svn 1.5 status ouput...
766 statuses = [' ' for i in range(7)] 776 statuses = [' '] * 7
767 # Col 0 777 # Col 0
768 xml_item_status = wc_status[0].getAttribute('item') 778 xml_item_status = wc_status[0].getAttribute('item')
769 if xml_item_status in status_letter: 779 if xml_item_status in status_letter:
770 statuses[0] = status_letter[xml_item_status] 780 statuses[0] = status_letter[xml_item_status]
771 else: 781 else:
772 raise Exception('Unknown item status "%s"; please implement me!' % 782 raise Exception('Unknown item status "%s"; please implement me!' %
773 xml_item_status) 783 xml_item_status)
774 # Col 1 784 # Col 1
775 xml_props_status = wc_status[0].getAttribute('props') 785 xml_props_status = wc_status[0].getAttribute('props')
776 if xml_props_status == 'modified': 786 if xml_props_status == 'modified':
777 statuses[1] = 'M' 787 statuses[1] = 'M'
778 elif xml_props_status == 'conflicted': 788 elif xml_props_status == 'conflicted':
779 statuses[1] = 'C' 789 statuses[1] = 'C'
780 elif (not xml_props_status or xml_props_status == 'none' or 790 elif (not xml_props_status or xml_props_status == 'none' or
781 xml_props_status == 'normal'): 791 xml_props_status == 'normal'):
782 pass 792 pass
783 else: 793 else:
784 raise Exception('Unknown props status "%s"; please implement me!' % 794 raise Exception('Unknown props status "%s"; please implement me!' %
785 xml_props_status) 795 xml_props_status)
786 # Col 2 796 # Col 2
787 if wc_status[0].getAttribute('wc-locked') == 'true': 797 if wc_status[0].getAttribute('wc-locked') == 'true':
788 statuses[2] = 'L' 798 statuses[2] = 'L'
789 # Col 3 799 # Col 3
790 if wc_status[0].getAttribute('copied') == 'true': 800 if wc_status[0].getAttribute('copied') == 'true':
791 statuses[3] = '+' 801 statuses[3] = '+'
792 # Col 4 802 # Col 4
793 if wc_status[0].getAttribute('switched') == 'true': 803 if wc_status[0].getAttribute('switched') == 'true':
794 statuses[4] = 'S' 804 statuses[4] = 'S'
795 # TODO(maruel): Col 5 and 6 805 # TODO(maruel): Col 5 and 6
796 item = (''.join(statuses), file) 806 item = (''.join(statuses), file_path)
797 results.append(item) 807 results.append(item)
798 return results 808 return results
OLDNEW
« gclient.py ('K') | « gclient.py ('k') | presubmit_canned_checks.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698