| 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 |