| OLD | NEW | 
|    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, | 
|   11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |   11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|   12 # See the License for the specific language governing permissions and |   12 # See the License for the specific language governing permissions and | 
|   13 # limitations under the License. |   13 # limitations under the License. | 
|   14  |   14  | 
|   15  |   15  | 
|   16 import os |   16 import os | 
|   17 import re |   17 import re | 
|   18 import subprocess |   18 import subprocess | 
|   19 import sys |   19 import sys | 
|   20 import xml.dom.minidom |   20 import xml.dom.minidom | 
|   21  |   21  | 
|   22 import gclient_utils |   22 import gclient_utils | 
|   23  |   23  | 
|   24 SVN_COMMAND = "svn" |   24 SVN_COMMAND = "svn" | 
|   25  |   25  | 
|   26  |   26  | 
|   27 ### SCM abstraction layer |   27 ### SCM abstraction layer | 
|   28  |   28  | 
|   29  |   29  | 
 |   30 # Factory Method for SCM wrapper creation | 
 |   31  | 
 |   32 def CreateSCM(url=None, root_dir=None, relpath=None, scm_name='svn'): | 
 |   33   # TODO(maruel): Deduce the SCM from the url. | 
 |   34   scm_map = { | 
 |   35     'svn' : SVNWrapper, | 
 |   36   } | 
 |   37   if not scm_name in scm_map: | 
 |   38     raise gclient_utils.Error('Unsupported scm %s' % scm_name) | 
 |   39   return scm_map[scm_name](url, root_dir, relpath, scm_name) | 
 |   40  | 
 |   41  | 
 |   42 # SCMWrapper base class | 
 |   43  | 
|   30 class SCMWrapper(object): |   44 class SCMWrapper(object): | 
|   31   """Add necessary glue between all the supported SCM. |   45   """Add necessary glue between all the supported SCM. | 
|   32  |   46  | 
|   33   This is the abstraction layer to bind to different SCM. Since currently only |   47   This is the abstraction layer to bind to different SCM. Since currently only | 
|   34   subversion is supported, a lot of subersionism remains. This can be sorted out |   48   subversion is supported, a lot of subersionism remains. This can be sorted out | 
|   35   once another SCM is supported.""" |   49   once another SCM is supported.""" | 
|   36   def __init__(self, url=None, root_dir=None, relpath=None, |   50   def __init__(self, url=None, root_dir=None, relpath=None, | 
|   37                scm_name='svn'): |   51                scm_name='svn'): | 
|   38     # TODO(maruel): Deduce the SCM from the url. |  | 
|   39     self.scm_name = scm_name |   52     self.scm_name = scm_name | 
|   40     self.url = url |   53     self.url = url | 
|   41     self._root_dir = root_dir |   54     self._root_dir = root_dir | 
|   42     if self._root_dir: |   55     if self._root_dir: | 
|   43       self._root_dir = self._root_dir.replace('/', os.sep) |   56       self._root_dir = self._root_dir.replace('/', os.sep) | 
|   44     self.relpath = relpath |   57     self.relpath = relpath | 
|   45     if self.relpath: |   58     if self.relpath: | 
|   46       self.relpath = self.relpath.replace('/', os.sep) |   59       self.relpath = self.relpath.replace('/', os.sep) | 
|   47  |   60  | 
|   48   def FullUrlForRelativeUrl(self, url): |   61   def FullUrlForRelativeUrl(self, url): | 
|   49     # Find the forth '/' and strip from there. A bit hackish. |   62     # Find the forth '/' and strip from there. A bit hackish. | 
|   50     return '/'.join(self.url.split('/')[:4]) + url |   63     return '/'.join(self.url.split('/')[:4]) + url | 
|   51  |   64  | 
|   52   def RunCommand(self, command, options, args, file_list=None): |   65   def RunCommand(self, command, options, args, file_list=None): | 
|   53     # file_list will have all files that are modified appended to it. |   66     # file_list will have all files that are modified appended to it. | 
|   54     if file_list is None: |   67     if file_list is None: | 
|   55       file_list = [] |   68       file_list = [] | 
|   56  |   69  | 
|   57     commands = { |   70     commands = ['cleanup', 'export', 'update', 'revert', | 
|   58       'cleanup':  self.cleanup, |   71                 'status', 'diff', 'pack', 'runhooks'] | 
|   59       'export':   self.export, |  | 
|   60       'update':   self.update, |  | 
|   61       'revert':   self.revert, |  | 
|   62       'status':   self.status, |  | 
|   63       'diff':     self.diff, |  | 
|   64       'pack':     self.pack, |  | 
|   65       'runhooks': self.status, |  | 
|   66     } |  | 
|   67  |   72  | 
|   68     if not command in commands: |   73     if not command in commands: | 
|   69       raise gclient_utils.Error('Unknown command %s' % command) |   74       raise gclient_utils.Error('Unknown command %s' % command) | 
|   70  |   75  | 
|   71     return commands[command](options, args, file_list) |   76     if not command in dir(self): | 
 |   77       raise gclient_utils.Error('Command %s not implemnted in %s wrapper' % ( | 
 |   78           command, self.scm_name)) | 
 |   79  | 
 |   80     return getattr(self, command)(options, args, file_list) | 
 |   81  | 
 |   82  | 
 |   83 class SVNWrapper(SCMWrapper): | 
 |   84   """ Wrapper for SVN """ | 
|   72  |   85  | 
|   73   def cleanup(self, options, args, file_list): |   86   def cleanup(self, options, args, file_list): | 
|   74     """Cleanup working copy.""" |   87     """Cleanup working copy.""" | 
|   75     command = ['cleanup'] |   88     command = ['cleanup'] | 
|   76     command.extend(args) |   89     command.extend(args) | 
|   77     RunSVN(command, os.path.join(self._root_dir, self.relpath)) |   90     RunSVN(command, os.path.join(self._root_dir, self.relpath)) | 
|   78  |   91  | 
|   79   def diff(self, options, args, file_list): |   92   def diff(self, options, args, file_list): | 
|   80     # NOTE: This function does not currently modify file_list. |   93     # NOTE: This function does not currently modify file_list. | 
|   81     command = ['diff'] |   94     command = ['diff'] | 
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  251                  os.path.join(self._root_dir, self.relpath)) |  264                  os.path.join(self._root_dir, self.relpath)) | 
|  252           accumulated_paths = [p] |  265           accumulated_paths = [p] | 
|  253           accumulated_length = len(p) |  266           accumulated_length = len(p) | 
|  254         else: |  267         else: | 
|  255           accumulated_paths.append(p) |  268           accumulated_paths.append(p) | 
|  256           accumulated_length += len(p) |  269           accumulated_length += len(p) | 
|  257       if accumulated_paths: |  270       if accumulated_paths: | 
|  258         RunSVN(command + accumulated_paths, |  271         RunSVN(command + accumulated_paths, | 
|  259                os.path.join(self._root_dir, self.relpath)) |  272                os.path.join(self._root_dir, self.relpath)) | 
|  260  |  273  | 
 |  274   def runhooks(self, options, args, file_list): | 
 |  275     self.status(options, args, file_list) | 
 |  276  | 
|  261   def status(self, options, args, file_list): |  277   def status(self, options, args, file_list): | 
|  262     """Display status information.""" |  278     """Display status information.""" | 
|  263     path = os.path.join(self._root_dir, self.relpath) |  279     path = os.path.join(self._root_dir, self.relpath) | 
|  264     command = ['status'] |  280     command = ['status'] | 
|  265     command.extend(args) |  281     command.extend(args) | 
|  266     if not os.path.isdir(path): |  282     if not os.path.isdir(path): | 
|  267       # svn status won't work if the directory doesn't exist. |  283       # svn status won't work if the directory doesn't exist. | 
|  268       print("\n________ couldn't run \'%s\' in \'%s\':\nThe directory " |  284       print("\n________ couldn't run \'%s\' in \'%s\':\nThe directory " | 
|  269             "does not exist." |  285             "does not exist." | 
|  270             % (' '.join(command), path)) |  286             % (' '.join(command), path)) | 
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  568                           xml_props_status) |  584                           xml_props_status) | 
|  569         # Col 2 |  585         # Col 2 | 
|  570         if wc_status[0].getAttribute('wc-locked') == 'true': |  586         if wc_status[0].getAttribute('wc-locked') == 'true': | 
|  571           statuses[2] = 'L' |  587           statuses[2] = 'L' | 
|  572         # Col 3 |  588         # Col 3 | 
|  573         if wc_status[0].getAttribute('copied') == 'true': |  589         if wc_status[0].getAttribute('copied') == 'true': | 
|  574           statuses[3] = '+' |  590           statuses[3] = '+' | 
|  575         item = (''.join(statuses), file) |  591         item = (''.join(statuses), file) | 
|  576         results.append(item) |  592         results.append(item) | 
|  577   return results |  593   return results | 
| OLD | NEW |