| OLD | NEW | 
|---|
| 1 # Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 # Copyright 2009 Google Inc.  All Rights Reserved. | 
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # | 
| 3 # found in the LICENSE file. | 3 # Licensed under the Apache License, Version 2.0 (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 | 
|  | 6 # | 
|  | 7 #      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 8 # | 
|  | 9 # Unless required by applicable law or agreed to in writing, software | 
|  | 10 # distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 12 # See the License for the specific language governing permissions and | 
|  | 13 # limitations under the License. | 
| 4 | 14 | 
| 5 """Gclient-specific SCM-specific operations.""" | 15 """Gclient-specific SCM-specific operations.""" | 
| 6 | 16 | 
| 7 import logging | 17 import logging | 
| 8 import os | 18 import os | 
| 9 import re | 19 import re | 
| 10 import subprocess | 20 import subprocess | 
|  | 21 import sys | 
|  | 22 import xml.dom.minidom | 
| 11 | 23 | 
| 12 import scm |  | 
| 13 import gclient_utils | 24 import gclient_utils | 
|  | 25 # TODO(maruel): Temporary. | 
|  | 26 from scm import CaptureGit, CaptureGitStatus, CaptureSVN | 
|  | 27 from scm import CaptureSVNHeadRevision, CaptureSVNInfo, CaptureSVNStatus | 
|  | 28 from scm import RunSVN, RunSVNAndFilterOutput, RunSVNAndGetFileList | 
| 14 | 29 | 
| 15 | 30 | 
| 16 ### SCM abstraction layer | 31 ### SCM abstraction layer | 
| 17 | 32 | 
|  | 33 | 
| 18 # Factory Method for SCM wrapper creation | 34 # Factory Method for SCM wrapper creation | 
| 19 | 35 | 
| 20 def CreateSCM(url=None, root_dir=None, relpath=None, scm_name='svn'): | 36 def CreateSCM(url=None, root_dir=None, relpath=None, scm_name='svn'): | 
| 21   # TODO(maruel): Deduce the SCM from the url. | 37   # TODO(maruel): Deduce the SCM from the url. | 
| 22   scm_map = { | 38   scm_map = { | 
| 23     'svn' : SVNWrapper, | 39     'svn' : SVNWrapper, | 
| 24     'git' : GitWrapper, | 40     'git' : GitWrapper, | 
| 25   } | 41   } | 
| 26 | 42 | 
| 27   if url and (url.startswith('git:') or | 43   if url and (url.startswith('git:') or | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 70     if not command in commands: | 86     if not command in commands: | 
| 71       raise gclient_utils.Error('Unknown command %s' % command) | 87       raise gclient_utils.Error('Unknown command %s' % command) | 
| 72 | 88 | 
| 73     if not command in dir(self): | 89     if not command in dir(self): | 
| 74       raise gclient_utils.Error('Command %s not implemnted in %s wrapper' % ( | 90       raise gclient_utils.Error('Command %s not implemnted in %s wrapper' % ( | 
| 75           command, self.scm_name)) | 91           command, self.scm_name)) | 
| 76 | 92 | 
| 77     return getattr(self, command)(options, args, file_list) | 93     return getattr(self, command)(options, args, file_list) | 
| 78 | 94 | 
| 79 | 95 | 
| 80 class GitWrapper(SCMWrapper, scm.GIT): | 96 class GitWrapper(SCMWrapper): | 
| 81   """Wrapper for Git""" | 97   """Wrapper for Git""" | 
| 82 | 98 | 
| 83   def cleanup(self, options, args, file_list): | 99   def cleanup(self, options, args, file_list): | 
| 84     """Cleanup working copy.""" | 100     """Cleanup working copy.""" | 
| 85     __pychecker__ = 'unusednames=args,file_list,options' | 101     __pychecker__ = 'unusednames=args,file_list,options' | 
| 86     self._Run(['prune'], redirect_stdout=False) | 102     self._RunGit(['prune'], redirect_stdout=False) | 
| 87     self._Run(['fsck'], redirect_stdout=False) | 103     self._RunGit(['fsck'], redirect_stdout=False) | 
| 88     self._Run(['gc'], redirect_stdout=False) | 104     self._RunGit(['gc'], redirect_stdout=False) | 
| 89 | 105 | 
| 90   def diff(self, options, args, file_list): | 106   def diff(self, options, args, file_list): | 
| 91     __pychecker__ = 'unusednames=args,file_list,options' | 107     __pychecker__ = 'unusednames=args,file_list,options' | 
| 92     merge_base = self._Run(['merge-base', 'HEAD', 'origin']) | 108     merge_base = self._RunGit(['merge-base', 'HEAD', 'origin']) | 
| 93     self._Run(['diff', merge_base], redirect_stdout=False) | 109     self._RunGit(['diff', merge_base], redirect_stdout=False) | 
| 94 | 110 | 
| 95   def export(self, options, args, file_list): | 111   def export(self, options, args, file_list): | 
| 96     __pychecker__ = 'unusednames=file_list,options' | 112     __pychecker__ = 'unusednames=file_list,options' | 
| 97     assert len(args) == 1 | 113     assert len(args) == 1 | 
| 98     export_path = os.path.abspath(os.path.join(args[0], self.relpath)) | 114     export_path = os.path.abspath(os.path.join(args[0], self.relpath)) | 
| 99     if not os.path.exists(export_path): | 115     if not os.path.exists(export_path): | 
| 100       os.makedirs(export_path) | 116       os.makedirs(export_path) | 
| 101     self._Run(['checkout-index', '-a', '--prefix=%s/' % export_path], | 117     self._RunGit(['checkout-index', '-a', '--prefix=%s/' % export_path], | 
| 102               redirect_stdout=False) | 118                  redirect_stdout=False) | 
| 103 | 119 | 
| 104   def update(self, options, args, file_list): | 120   def update(self, options, args, file_list): | 
| 105     """Runs git to update or transparently checkout the working copy. | 121     """Runs git to update or transparently checkout the working copy. | 
| 106 | 122 | 
| 107     All updated files will be appended to file_list. | 123     All updated files will be appended to file_list. | 
| 108 | 124 | 
| 109     Raises: | 125     Raises: | 
| 110       Error: if can't get URL for relative path. | 126       Error: if can't get URL for relative path. | 
| 111     """ | 127     """ | 
| 112 | 128 | 
| 113     if args: | 129     if args: | 
| 114       raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args)) | 130       raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args)) | 
| 115 | 131 | 
| 116     url, revision = gclient_utils.SplitUrlRevision(self.url) | 132     url, revision = gclient_utils.SplitUrlRevision(self.url) | 
| 117     rev_str = "" | 133     rev_str = "" | 
| 118     if options.revision: | 134     if options.revision: | 
| 119       # Override the revision number. | 135       # Override the revision number. | 
| 120       revision = str(options.revision) | 136       revision = str(options.revision) | 
| 121     if revision: | 137     if revision: | 
| 122       url = '%s@%s' % (url, revision) | 138       url = '%s@%s' % (url, revision) | 
| 123       rev_str = ' at %s' % revision | 139       rev_str = ' at %s' % revision | 
| 124 | 140 | 
| 125     if options.verbose: | 141     if options.verbose: | 
| 126       print("\n_____ %s%s" % (self.relpath, rev_str)) | 142       print("\n_____ %s%s" % (self.relpath, rev_str)) | 
| 127 | 143 | 
| 128     if not os.path.exists(self.checkout_path): | 144     if not os.path.exists(self.checkout_path): | 
| 129       self._Run(['clone', url, self.checkout_path], | 145       self._RunGit(['clone', url, self.checkout_path], | 
| 130                 cwd=self._root_dir, redirect_stdout=False) | 146                    cwd=self._root_dir, redirect_stdout=False) | 
| 131       if revision: | 147       if revision: | 
| 132         self._Run(['reset', '--hard', revision], redirect_stdout=False) | 148         self._RunGit(['reset', '--hard', revision], redirect_stdout=False) | 
| 133       files = self._Run(['ls-files']).split() | 149       files =  self._RunGit(['ls-files']).split() | 
| 134       file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | 150       file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | 
| 135       return | 151       return | 
| 136 | 152 | 
| 137     self._Run(['remote', 'update'], redirect_stdout=False) | 153     self._RunGit(['remote', 'update'], redirect_stdout=False) | 
| 138     new_base = 'origin' | 154     new_base = 'origin' | 
| 139     if revision: | 155     if revision: | 
| 140       new_base = revision | 156       new_base = revision | 
| 141     files = self._Run(['diff', new_base, '--name-only']).split() | 157     files = self._RunGit(['diff', new_base, '--name-only']).split() | 
| 142     file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | 158     file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | 
| 143     self._Run(['rebase', '-v', new_base], redirect_stdout=False) | 159     self._RunGit(['rebase', '-v', new_base], redirect_stdout=False) | 
| 144     print "Checked out revision %s." % self.revinfo(options, (), None) | 160     print "Checked out revision %s." % self.revinfo(options, (), None) | 
| 145 | 161 | 
| 146   def revert(self, options, args, file_list): | 162   def revert(self, options, args, file_list): | 
| 147     """Reverts local modifications. | 163     """Reverts local modifications. | 
| 148 | 164 | 
| 149     All reverted files will be appended to file_list. | 165     All reverted files will be appended to file_list. | 
| 150     """ | 166     """ | 
| 151     __pychecker__ = 'unusednames=args' | 167     __pychecker__ = 'unusednames=args' | 
| 152     path = os.path.join(self._root_dir, self.relpath) | 168     path = os.path.join(self._root_dir, self.relpath) | 
| 153     if not os.path.isdir(path): | 169     if not os.path.isdir(path): | 
| 154       # revert won't work if the directory doesn't exist. It needs to | 170       # revert won't work if the directory doesn't exist. It needs to | 
| 155       # checkout instead. | 171       # checkout instead. | 
| 156       print("\n_____ %s is missing, synching instead" % self.relpath) | 172       print("\n_____ %s is missing, synching instead" % self.relpath) | 
| 157       # Don't reuse the args. | 173       # Don't reuse the args. | 
| 158       return self.update(options, [], file_list) | 174       return self.update(options, [], file_list) | 
| 159     merge_base = self._Run(['merge-base', 'HEAD', 'origin']) | 175     merge_base = self._RunGit(['merge-base', 'HEAD', 'origin']) | 
| 160     files = self._Run(['diff', merge_base, '--name-only']).split() | 176     files = self._RunGit(['diff', merge_base, '--name-only']).split() | 
| 161     self._Run(['reset', '--hard', merge_base], redirect_stdout=False) | 177     self._RunGit(['reset', '--hard', merge_base], redirect_stdout=False) | 
| 162     file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | 178     file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | 
| 163 | 179 | 
| 164   def revinfo(self, options, args, file_list): | 180   def revinfo(self, options, args, file_list): | 
| 165     """Display revision""" | 181     """Display revision""" | 
| 166     __pychecker__ = 'unusednames=args,file_list,options' | 182     __pychecker__ = 'unusednames=args,file_list,options' | 
| 167     return self._Run(['rev-parse', 'HEAD']) | 183     return self._RunGit(['rev-parse', 'HEAD']) | 
| 168 | 184 | 
| 169   def runhooks(self, options, args, file_list): | 185   def runhooks(self, options, args, file_list): | 
| 170     self.status(options, args, file_list) | 186     self.status(options, args, file_list) | 
| 171 | 187 | 
| 172   def status(self, options, args, file_list): | 188   def status(self, options, args, file_list): | 
| 173     """Display status information.""" | 189     """Display status information.""" | 
| 174     __pychecker__ = 'unusednames=args,options' | 190     __pychecker__ = 'unusednames=args,options' | 
| 175     if not os.path.isdir(self.checkout_path): | 191     if not os.path.isdir(self.checkout_path): | 
| 176       print('\n________ couldn\'t run status in %s:\nThe directory ' | 192       print('\n________ couldn\'t run status in %s:\nThe directory ' | 
| 177             'does not exist.' % self.checkout_path) | 193             'does not exist.' % self.checkout_path) | 
| 178     else: | 194     else: | 
| 179       merge_base = self._Run(['merge-base', 'HEAD', 'origin']) | 195       merge_base = self._RunGit(['merge-base', 'HEAD', 'origin']) | 
| 180       self._Run(['diff', '--name-status', merge_base], redirect_stdout=False) | 196       self._RunGit(['diff', '--name-status', merge_base], redirect_stdout=False) | 
| 181       files = self._Run(['diff', '--name-only', merge_base]).split() | 197       files = self._RunGit(['diff', '--name-only', merge_base]).split() | 
| 182       file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | 198       file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | 
| 183 | 199 | 
| 184   def _Run(self, args, cwd=None, checkrc=True, redirect_stdout=True): | 200   def _RunGit(self, args, cwd=None, checkrc=True, redirect_stdout=True): | 
| 185     # TODO(maruel): Merge with Capture? |  | 
| 186     stdout=None | 201     stdout=None | 
| 187     if redirect_stdout: | 202     if redirect_stdout: | 
| 188       stdout=subprocess.PIPE | 203       stdout=subprocess.PIPE | 
| 189     if cwd == None: | 204     if cwd == None: | 
| 190       cwd = self.checkout_path | 205       cwd = self.checkout_path | 
| 191     cmd = [self.COMMAND] | 206     cmd = ['git'] | 
| 192     cmd.extend(args) | 207     cmd.extend(args) | 
| 193     sp = subprocess.Popen(cmd, cwd=cwd, stdout=stdout) | 208     sp = subprocess.Popen(cmd, cwd=cwd, stdout=stdout) | 
| 194     if checkrc and sp.returncode: | 209     if checkrc and sp.returncode: | 
| 195       raise gclient_utils.Error('git command %s returned %d' % | 210       raise gclient_utils.Error('git command %s returned %d' % | 
| 196                                 (args[0], sp.returncode)) | 211                                 (args[0], sp.returncode)) | 
| 197     output = sp.communicate()[0] | 212     output = sp.communicate()[0] | 
| 198     if output is not None: | 213     if output != None: | 
| 199       return output.strip() | 214       return output.strip() | 
| 200 | 215 | 
| 201 | 216 | 
| 202 class SVNWrapper(SCMWrapper, scm.SVN): | 217 class SVNWrapper(SCMWrapper): | 
| 203   """ Wrapper for SVN """ | 218   """ Wrapper for SVN """ | 
| 204 | 219 | 
| 205   def cleanup(self, options, args, file_list): | 220   def cleanup(self, options, args, file_list): | 
| 206     """Cleanup working copy.""" | 221     """Cleanup working copy.""" | 
| 207     __pychecker__ = 'unusednames=file_list,options' | 222     __pychecker__ = 'unusednames=file_list,options' | 
| 208     command = ['cleanup'] | 223     command = ['cleanup'] | 
| 209     command.extend(args) | 224     command.extend(args) | 
| 210     self.Run(command, os.path.join(self._root_dir, self.relpath)) | 225     RunSVN(command, os.path.join(self._root_dir, self.relpath)) | 
| 211 | 226 | 
| 212   def diff(self, options, args, file_list): | 227   def diff(self, options, args, file_list): | 
| 213     # NOTE: This function does not currently modify file_list. | 228     # NOTE: This function does not currently modify file_list. | 
| 214     __pychecker__ = 'unusednames=file_list,options' | 229     __pychecker__ = 'unusednames=file_list,options' | 
| 215     command = ['diff'] | 230     command = ['diff'] | 
| 216     command.extend(args) | 231     command.extend(args) | 
| 217     self.Run(command, os.path.join(self._root_dir, self.relpath)) | 232     RunSVN(command, os.path.join(self._root_dir, self.relpath)) | 
| 218 | 233 | 
| 219   def export(self, options, args, file_list): | 234   def export(self, options, args, file_list): | 
| 220     __pychecker__ = 'unusednames=file_list,options' | 235     __pychecker__ = 'unusednames=file_list,options' | 
| 221     assert len(args) == 1 | 236     assert len(args) == 1 | 
| 222     export_path = os.path.abspath(os.path.join(args[0], self.relpath)) | 237     export_path = os.path.abspath(os.path.join(args[0], self.relpath)) | 
| 223     try: | 238     try: | 
| 224       os.makedirs(export_path) | 239       os.makedirs(export_path) | 
| 225     except OSError: | 240     except OSError: | 
| 226       pass | 241       pass | 
| 227     assert os.path.exists(export_path) | 242     assert os.path.exists(export_path) | 
| 228     command = ['export', '--force', '.'] | 243     command = ['export', '--force', '.'] | 
| 229     command.append(export_path) | 244     command.append(export_path) | 
| 230     self.Run(command, os.path.join(self._root_dir, self.relpath)) | 245     RunSVN(command, os.path.join(self._root_dir, self.relpath)) | 
| 231 | 246 | 
| 232   def update(self, options, args, file_list): | 247   def update(self, options, args, file_list): | 
| 233     """Runs SCM to update or transparently checkout the working copy. | 248     """Runs SCM to update or transparently checkout the working copy. | 
| 234 | 249 | 
| 235     All updated files will be appended to file_list. | 250     All updated files will be appended to file_list. | 
| 236 | 251 | 
| 237     Raises: | 252     Raises: | 
| 238       Error: if can't get URL for relative path. | 253       Error: if can't get URL for relative path. | 
| 239     """ | 254     """ | 
| 240     # Only update if git is not controlling the directory. | 255     # Only update if git is not controlling the directory. | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 257     if revision: | 272     if revision: | 
| 258       forced_revision = True | 273       forced_revision = True | 
| 259       url = '%s@%s' % (url, revision) | 274       url = '%s@%s' % (url, revision) | 
| 260       rev_str = ' at %s' % revision | 275       rev_str = ' at %s' % revision | 
| 261 | 276 | 
| 262     if not os.path.exists(checkout_path): | 277     if not os.path.exists(checkout_path): | 
| 263       # We need to checkout. | 278       # We need to checkout. | 
| 264       command = ['checkout', url, checkout_path] | 279       command = ['checkout', url, checkout_path] | 
| 265       if revision: | 280       if revision: | 
| 266         command.extend(['--revision', str(revision)]) | 281         command.extend(['--revision', str(revision)]) | 
| 267       self.RunAndGetFileList(options, command, self._root_dir, file_list) | 282       RunSVNAndGetFileList(options, command, self._root_dir, file_list) | 
| 268       return | 283       return | 
| 269 | 284 | 
| 270     # Get the existing scm url and the revision number of the current checkout. | 285     # Get the existing scm url and the revision number of the current checkout. | 
| 271     from_info = self.CaptureInfo(os.path.join(checkout_path, '.'), '.') | 286     from_info = CaptureSVNInfo(os.path.join(checkout_path, '.'), '.') | 
| 272     if not from_info: | 287     if not from_info: | 
| 273       raise gclient_utils.Error("Can't update/checkout %r if an unversioned " | 288       raise gclient_utils.Error("Can't update/checkout %r if an unversioned " | 
| 274                                 "directory is present. Delete the directory " | 289                                 "directory is present. Delete the directory " | 
| 275                                 "and try again." % | 290                                 "and try again." % | 
| 276                                 checkout_path) | 291                                 checkout_path) | 
| 277 | 292 | 
| 278     if options.manually_grab_svn_rev: | 293     if options.manually_grab_svn_rev: | 
| 279       # Retrieve the current HEAD version because svn is slow at null updates. | 294       # Retrieve the current HEAD version because svn is slow at null updates. | 
| 280       if not revision: | 295       if not revision: | 
| 281         from_info_live = self.CaptureInfo(from_info['URL'], '.') | 296         from_info_live = CaptureSVNInfo(from_info['URL'], '.') | 
| 282         revision = str(from_info_live['Revision']) | 297         revision = str(from_info_live['Revision']) | 
| 283         rev_str = ' at %s' % revision | 298         rev_str = ' at %s' % revision | 
| 284 | 299 | 
| 285     if from_info['URL'] != base_url: | 300     if from_info['URL'] != base_url: | 
| 286       to_info = self.CaptureInfo(url, '.') | 301       to_info = CaptureSVNInfo(url, '.') | 
| 287       if not to_info.get('Repository Root') or not to_info.get('UUID'): | 302       if not to_info.get('Repository Root') or not to_info.get('UUID'): | 
| 288         # The url is invalid or the server is not accessible, it's safer to bail | 303         # The url is invalid or the server is not accessible, it's safer to bail | 
| 289         # out right now. | 304         # out right now. | 
| 290         raise gclient_utils.Error('This url is unreachable: %s' % url) | 305         raise gclient_utils.Error('This url is unreachable: %s' % url) | 
| 291       can_switch = ((from_info['Repository Root'] != to_info['Repository Root']) | 306       can_switch = ((from_info['Repository Root'] != to_info['Repository Root']) | 
| 292                     and (from_info['UUID'] == to_info['UUID'])) | 307                     and (from_info['UUID'] == to_info['UUID'])) | 
| 293       if can_switch: | 308       if can_switch: | 
| 294         print("\n_____ relocating %s to a new checkout" % self.relpath) | 309         print("\n_____ relocating %s to a new checkout" % self.relpath) | 
| 295         # We have different roots, so check if we can switch --relocate. | 310         # We have different roots, so check if we can switch --relocate. | 
| 296         # Subversion only permits this if the repository UUIDs match. | 311         # Subversion only permits this if the repository UUIDs match. | 
| 297         # Perform the switch --relocate, then rewrite the from_url | 312         # Perform the switch --relocate, then rewrite the from_url | 
| 298         # to reflect where we "are now."  (This is the same way that | 313         # to reflect where we "are now."  (This is the same way that | 
| 299         # Subversion itself handles the metadata when switch --relocate | 314         # Subversion itself handles the metadata when switch --relocate | 
| 300         # is used.)  This makes the checks below for whether we | 315         # is used.)  This makes the checks below for whether we | 
| 301         # can update to a revision or have to switch to a different | 316         # can update to a revision or have to switch to a different | 
| 302         # branch work as expected. | 317         # branch work as expected. | 
| 303         # TODO(maruel):  TEST ME ! | 318         # TODO(maruel):  TEST ME ! | 
| 304         command = ["switch", "--relocate", | 319         command = ["switch", "--relocate", | 
| 305                    from_info['Repository Root'], | 320                    from_info['Repository Root'], | 
| 306                    to_info['Repository Root'], | 321                    to_info['Repository Root'], | 
| 307                    self.relpath] | 322                    self.relpath] | 
| 308         self.Run(command, self._root_dir) | 323         RunSVN(command, self._root_dir) | 
| 309         from_info['URL'] = from_info['URL'].replace( | 324         from_info['URL'] = from_info['URL'].replace( | 
| 310             from_info['Repository Root'], | 325             from_info['Repository Root'], | 
| 311             to_info['Repository Root']) | 326             to_info['Repository Root']) | 
| 312       else: | 327       else: | 
| 313         if self.CaptureStatus(checkout_path): | 328         if CaptureSVNStatus(checkout_path): | 
| 314           raise gclient_utils.Error("Can't switch the checkout to %s; UUID " | 329           raise gclient_utils.Error("Can't switch the checkout to %s; UUID " | 
| 315                                     "don't match and there is local changes " | 330                                     "don't match and there is local changes " | 
| 316                                     "in %s. Delete the directory and " | 331                                     "in %s. Delete the directory and " | 
| 317                                     "try again." % (url, checkout_path)) | 332                                     "try again." % (url, checkout_path)) | 
| 318         # Ok delete it. | 333         # Ok delete it. | 
| 319         print("\n_____ switching %s to a new checkout" % self.relpath) | 334         print("\n_____ switching %s to a new checkout" % self.relpath) | 
| 320         gclient_utils.RemoveDirectory(checkout_path) | 335         gclient_utils.RemoveDirectory(checkout_path) | 
| 321         # We need to checkout. | 336         # We need to checkout. | 
| 322         command = ['checkout', url, checkout_path] | 337         command = ['checkout', url, checkout_path] | 
| 323         if revision: | 338         if revision: | 
| 324           command.extend(['--revision', str(revision)]) | 339           command.extend(['--revision', str(revision)]) | 
| 325         self.RunAndGetFileList(options, command, self._root_dir, file_list) | 340         RunSVNAndGetFileList(options, command, self._root_dir, file_list) | 
| 326         return | 341         return | 
| 327 | 342 | 
| 328 | 343 | 
| 329     # If the provided url has a revision number that matches the revision | 344     # If the provided url has a revision number that matches the revision | 
| 330     # number of the existing directory, then we don't need to bother updating. | 345     # number of the existing directory, then we don't need to bother updating. | 
| 331     if not options.force and str(from_info['Revision']) == revision: | 346     if not options.force and str(from_info['Revision']) == revision: | 
| 332       if options.verbose or not forced_revision: | 347       if options.verbose or not forced_revision: | 
| 333         print("\n_____ %s%s" % (self.relpath, rev_str)) | 348         print("\n_____ %s%s" % (self.relpath, rev_str)) | 
| 334       return | 349       return | 
| 335 | 350 | 
| 336     command = ["update", checkout_path] | 351     command = ["update", checkout_path] | 
| 337     if revision: | 352     if revision: | 
| 338       command.extend(['--revision', str(revision)]) | 353       command.extend(['--revision', str(revision)]) | 
| 339     self.RunAndGetFileList(options, command, self._root_dir, file_list) | 354     RunSVNAndGetFileList(options, command, self._root_dir, file_list) | 
| 340 | 355 | 
| 341   def revert(self, options, args, file_list): | 356   def revert(self, options, args, file_list): | 
| 342     """Reverts local modifications. Subversion specific. | 357     """Reverts local modifications. Subversion specific. | 
| 343 | 358 | 
| 344     All reverted files will be appended to file_list, even if Subversion | 359     All reverted files will be appended to file_list, even if Subversion | 
| 345     doesn't know about them. | 360     doesn't know about them. | 
| 346     """ | 361     """ | 
| 347     __pychecker__ = 'unusednames=args' | 362     __pychecker__ = 'unusednames=args' | 
| 348     path = os.path.join(self._root_dir, self.relpath) | 363     path = os.path.join(self._root_dir, self.relpath) | 
| 349     if not os.path.isdir(path): | 364     if not os.path.isdir(path): | 
| 350       # svn revert won't work if the directory doesn't exist. It needs to | 365       # svn revert won't work if the directory doesn't exist. It needs to | 
| 351       # checkout instead. | 366       # checkout instead. | 
| 352       print("\n_____ %s is missing, synching instead" % self.relpath) | 367       print("\n_____ %s is missing, synching instead" % self.relpath) | 
| 353       # Don't reuse the args. | 368       # Don't reuse the args. | 
| 354       return self.update(options, [], file_list) | 369       return self.update(options, [], file_list) | 
| 355 | 370 | 
| 356     for file_status in self.CaptureStatus(path): | 371     for file_status in CaptureSVNStatus(path): | 
| 357       file_path = os.path.join(path, file_status[1]) | 372       file_path = os.path.join(path, file_status[1]) | 
| 358       if file_status[0][0] == 'X': | 373       if file_status[0][0] == 'X': | 
| 359         # Ignore externals. | 374         # Ignore externals. | 
| 360         logging.info('Ignoring external %s' % file_path) | 375         logging.info('Ignoring external %s' % file_path) | 
| 361         continue | 376         continue | 
| 362 | 377 | 
| 363       if logging.getLogger().isEnabledFor(logging.INFO): | 378       if logging.getLogger().isEnabledFor(logging.INFO): | 
| 364         logging.info('%s%s' % (file[0], file[1])) | 379         logging.info('%s%s' % (file[0], file[1])) | 
| 365       else: | 380       else: | 
| 366         print(file_path) | 381         print(file_path) | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 381           gclient_utils.RemoveDirectory(file_path) | 396           gclient_utils.RemoveDirectory(file_path) | 
| 382         else: | 397         else: | 
| 383           logging.error('no idea what is %s.\nYou just found a bug in gclient' | 398           logging.error('no idea what is %s.\nYou just found a bug in gclient' | 
| 384                         ', please ping maruel@chromium.org ASAP!' % file_path) | 399                         ', please ping maruel@chromium.org ASAP!' % file_path) | 
| 385       except EnvironmentError: | 400       except EnvironmentError: | 
| 386         logging.error('Failed to remove %s.' % file_path) | 401         logging.error('Failed to remove %s.' % file_path) | 
| 387 | 402 | 
| 388     try: | 403     try: | 
| 389       # svn revert is so broken we don't even use it. Using | 404       # svn revert is so broken we don't even use it. Using | 
| 390       # "svn up --revision BASE" achieve the same effect. | 405       # "svn up --revision BASE" achieve the same effect. | 
| 391       self.RunAndGetFileList(options, ['update', '--revision', 'BASE'], path, | 406       RunSVNAndGetFileList(options, ['update', '--revision', 'BASE'], path, | 
| 392                            file_list) | 407                            file_list) | 
| 393     except OSError, e: | 408     except OSError, e: | 
| 394       # Maybe the directory disapeared meanwhile. We don't want it to throw an | 409       # Maybe the directory disapeared meanwhile. We don't want it to throw an | 
| 395       # exception. | 410       # exception. | 
| 396       logging.error('Failed to update:\n%s' % str(e)) | 411       logging.error('Failed to update:\n%s' % str(e)) | 
| 397 | 412 | 
| 398   def revinfo(self, options, args, file_list): | 413   def revinfo(self, options, args, file_list): | 
| 399     """Display revision""" | 414     """Display revision""" | 
| 400     __pychecker__ = 'unusednames=args,file_list,options' | 415     __pychecker__ = 'unusednames=args,file_list,options' | 
| 401     return self.CaptureHeadRevision(self.url) | 416     return CaptureSVNHeadRevision(self.url) | 
| 402 | 417 | 
| 403   def runhooks(self, options, args, file_list): | 418   def runhooks(self, options, args, file_list): | 
| 404     self.status(options, args, file_list) | 419     self.status(options, args, file_list) | 
| 405 | 420 | 
| 406   def status(self, options, args, file_list): | 421   def status(self, options, args, file_list): | 
| 407     """Display status information.""" | 422     """Display status information.""" | 
| 408     path = os.path.join(self._root_dir, self.relpath) | 423     path = os.path.join(self._root_dir, self.relpath) | 
| 409     command = ['status'] | 424     command = ['status'] | 
| 410     command.extend(args) | 425     command.extend(args) | 
| 411     if not os.path.isdir(path): | 426     if not os.path.isdir(path): | 
| 412       # svn status won't work if the directory doesn't exist. | 427       # svn status won't work if the directory doesn't exist. | 
| 413       print("\n________ couldn't run \'%s\' in \'%s\':\nThe directory " | 428       print("\n________ couldn't run \'%s\' in \'%s\':\nThe directory " | 
| 414             "does not exist." | 429             "does not exist." | 
| 415             % (' '.join(command), path)) | 430             % (' '.join(command), path)) | 
| 416       # There's no file list to retrieve. | 431       # There's no file list to retrieve. | 
| 417     else: | 432     else: | 
| 418       self.RunAndGetFileList(options, command, path, file_list) | 433       RunSVNAndGetFileList(options, command, path, file_list) | 
| 419 | 434 | 
| 420   def pack(self, options, args, file_list): | 435   def pack(self, options, args, file_list): | 
| 421     """Generates a patch file which can be applied to the root of the | 436     """Generates a patch file which can be applied to the root of the | 
| 422     repository.""" | 437     repository.""" | 
| 423     __pychecker__ = 'unusednames=file_list,options' | 438     __pychecker__ = 'unusednames=file_list,options' | 
| 424     path = os.path.join(self._root_dir, self.relpath) | 439     path = os.path.join(self._root_dir, self.relpath) | 
| 425     command = ['diff'] | 440     command = ['diff'] | 
| 426     command.extend(args) | 441     command.extend(args) | 
| 427     # Simple class which tracks which file is being diffed and | 442     # Simple class which tracks which file is being diffed and | 
| 428     # replaces instances of its file name in the original and | 443     # replaces instances of its file name in the original and | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
| 453           self.SetCurrentFile(line[len(self.index_string):]) | 468           self.SetCurrentFile(line[len(self.index_string):]) | 
| 454           self.ReplaceAndPrint(line) | 469           self.ReplaceAndPrint(line) | 
| 455         else: | 470         else: | 
| 456           if (line.startswith(self.original_prefix) or | 471           if (line.startswith(self.original_prefix) or | 
| 457               line.startswith(self.working_prefix)): | 472               line.startswith(self.working_prefix)): | 
| 458             self.ReplaceAndPrint(line) | 473             self.ReplaceAndPrint(line) | 
| 459           else: | 474           else: | 
| 460             print line | 475             print line | 
| 461 | 476 | 
| 462     filterer = DiffFilterer(self.relpath) | 477     filterer = DiffFilterer(self.relpath) | 
| 463     self.RunAndFilterOutput(command, path, False, False, filterer.Filter) | 478     RunSVNAndFilterOutput(command, path, False, False, filterer.Filter) | 
| OLD | NEW | 
|---|