| OLD | NEW |
| 1 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """Gclient-specific SCM-specific operations.""" | 5 """Gclient-specific SCM-specific operations.""" |
| 6 | 6 |
| 7 import logging | 7 import logging |
| 8 import os | 8 import os |
| 9 import posixpath | 9 import posixpath |
| 10 import re | 10 import re |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 line.startswith(self.working_prefix)): | 48 line.startswith(self.working_prefix)): |
| 49 self.ReplaceAndPrint(line) | 49 self.ReplaceAndPrint(line) |
| 50 else: | 50 else: |
| 51 print line | 51 print line |
| 52 | 52 |
| 53 | 53 |
| 54 ### SCM abstraction layer | 54 ### SCM abstraction layer |
| 55 | 55 |
| 56 # Factory Method for SCM wrapper creation | 56 # Factory Method for SCM wrapper creation |
| 57 | 57 |
| 58 def CreateSCM(url=None, root_dir=None, relpath=None, scm_name='svn'): | 58 def GetScmName(url): |
| 59 scm_map = { | 59 if url: |
| 60 url, _ = gclient_utils.SplitUrlRevision(url) |
| 61 if (url.startswith('git://') or url.startswith('ssh://') or |
| 62 url.endswith('.git')): |
| 63 return 'git' |
| 64 elif (url.startswith('http://') or url.startswith('svn://') or |
| 65 url.startswith('ssh+svn://')): |
| 66 return 'svn' |
| 67 return None |
| 68 |
| 69 |
| 70 def CreateSCM(url, root_dir=None, relpath=None): |
| 71 SCM_MAP = { |
| 60 'svn' : SVNWrapper, | 72 'svn' : SVNWrapper, |
| 61 'git' : GitWrapper, | 73 'git' : GitWrapper, |
| 62 } | 74 } |
| 63 | 75 |
| 64 orig_url = url | 76 scm_name = GetScmName(url) |
| 65 | 77 if not scm_name in SCM_MAP: |
| 66 if url: | 78 raise gclient_utils.Error('No SCM found for url %s' % url) |
| 67 url, _ = gclient_utils.SplitUrlRevision(url) | 79 return SCM_MAP[scm_name](url, root_dir, relpath) |
| 68 if url.startswith('git:') or url.startswith('ssh:') or url.endswith('.git'): | |
| 69 scm_name = 'git' | |
| 70 | |
| 71 if not scm_name in scm_map: | |
| 72 raise gclient_utils.Error('Unsupported scm %s' % scm_name) | |
| 73 return scm_map[scm_name](orig_url, root_dir, relpath, scm_name) | |
| 74 | 80 |
| 75 | 81 |
| 76 # SCMWrapper base class | 82 # SCMWrapper base class |
| 77 | 83 |
| 78 class SCMWrapper(object): | 84 class SCMWrapper(object): |
| 79 """Add necessary glue between all the supported SCM. | 85 """Add necessary glue between all the supported SCM. |
| 80 | 86 |
| 81 This is the abstraction layer to bind to different SCM. | 87 This is the abstraction layer to bind to different SCM. |
| 82 """ | 88 """ |
| 83 def __init__(self, url=None, root_dir=None, relpath=None, | 89 def __init__(self, url=None, root_dir=None, relpath=None): |
| 84 scm_name='svn'): | |
| 85 self.scm_name = scm_name | |
| 86 self.url = url | 90 self.url = url |
| 87 self._root_dir = root_dir | 91 self._root_dir = root_dir |
| 88 if self._root_dir: | 92 if self._root_dir: |
| 89 self._root_dir = self._root_dir.replace('/', os.sep) | 93 self._root_dir = self._root_dir.replace('/', os.sep) |
| 90 self.relpath = relpath | 94 self.relpath = relpath |
| 91 if self.relpath: | 95 if self.relpath: |
| 92 self.relpath = self.relpath.replace('/', os.sep) | 96 self.relpath = self.relpath.replace('/', os.sep) |
| 93 if self.relpath and self._root_dir: | 97 if self.relpath and self._root_dir: |
| 94 self.checkout_path = os.path.join(self._root_dir, self.relpath) | 98 self.checkout_path = os.path.join(self._root_dir, self.relpath) |
| 95 | 99 |
| 96 def RunCommand(self, command, options, args, file_list=None): | 100 def RunCommand(self, command, options, args, file_list=None): |
| 97 # file_list will have all files that are modified appended to it. | 101 # file_list will have all files that are modified appended to it. |
| 98 if file_list is None: | 102 if file_list is None: |
| 99 file_list = [] | 103 file_list = [] |
| 100 | 104 |
| 101 commands = ['cleanup', 'export', 'update', 'updatesingle', 'revert', | 105 commands = ['cleanup', 'export', 'update', 'updatesingle', 'revert', |
| 102 'revinfo', 'status', 'diff', 'pack', 'runhooks'] | 106 'revinfo', 'status', 'diff', 'pack', 'runhooks'] |
| 103 | 107 |
| 104 if not command in commands: | 108 if not command in commands: |
| 105 raise gclient_utils.Error('Unknown command %s' % command) | 109 raise gclient_utils.Error('Unknown command %s' % command) |
| 106 | 110 |
| 107 if not command in dir(self): | 111 if not command in dir(self): |
| 108 raise gclient_utils.Error('Command %s not implemented in %s wrapper' % ( | 112 raise gclient_utils.Error('Command %s not implemented in %s wrapper' % ( |
| 109 command, self.scm_name)) | 113 command, self.__class__.__name__)) |
| 110 | 114 |
| 111 return getattr(self, command)(options, args, file_list) | 115 return getattr(self, command)(options, args, file_list) |
| 112 | 116 |
| 113 | 117 |
| 114 class GitWrapper(SCMWrapper): | 118 class GitWrapper(SCMWrapper): |
| 115 """Wrapper for Git""" | 119 """Wrapper for Git""" |
| 116 | 120 |
| 117 @staticmethod | 121 @staticmethod |
| 118 def cleanup(options, args, file_list): | 122 def cleanup(options, args, file_list): |
| 119 """'Cleanup' the repo. | 123 """'Cleanup' the repo. |
| (...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 """ Wrapper for SVN """ | 668 """ Wrapper for SVN """ |
| 665 | 669 |
| 666 def cleanup(self, options, args, file_list): | 670 def cleanup(self, options, args, file_list): |
| 667 """Cleanup working copy.""" | 671 """Cleanup working copy.""" |
| 668 command = ['cleanup'] | 672 command = ['cleanup'] |
| 669 command.extend(args) | 673 command.extend(args) |
| 670 scm.SVN.Run(command, os.path.join(self._root_dir, self.relpath)) | 674 scm.SVN.Run(command, os.path.join(self._root_dir, self.relpath)) |
| 671 | 675 |
| 672 def diff(self, options, args, file_list): | 676 def diff(self, options, args, file_list): |
| 673 # NOTE: This function does not currently modify file_list. | 677 # NOTE: This function does not currently modify file_list. |
| 678 path = os.path.join(self._root_dir, self.relpath) |
| 679 if not os.path.isdir(path): |
| 680 raise gclient_utils.Error('Directory %s is not present.' % path) |
| 674 command = ['diff'] | 681 command = ['diff'] |
| 675 command.extend(args) | 682 command.extend(args) |
| 676 scm.SVN.Run(command, os.path.join(self._root_dir, self.relpath)) | 683 scm.SVN.Run(command, path) |
| 677 | 684 |
| 678 def export(self, options, args, file_list): | 685 def export(self, options, args, file_list): |
| 679 """Export a clean directory tree into the given path.""" | 686 """Export a clean directory tree into the given path.""" |
| 680 assert len(args) == 1 | 687 assert len(args) == 1 |
| 681 export_path = os.path.abspath(os.path.join(args[0], self.relpath)) | 688 export_path = os.path.abspath(os.path.join(args[0], self.relpath)) |
| 682 try: | 689 try: |
| 683 os.makedirs(export_path) | 690 os.makedirs(export_path) |
| 684 except OSError: | 691 except OSError: |
| 685 pass | 692 pass |
| 686 assert os.path.exists(export_path) | 693 assert os.path.exists(export_path) |
| 687 command = ['export', '--force', '.'] | 694 command = ['export', '--force', '.'] |
| 688 command.append(export_path) | 695 command.append(export_path) |
| 689 scm.SVN.Run(command, os.path.join(self._root_dir, self.relpath)) | 696 scm.SVN.Run(command, os.path.join(self._root_dir, self.relpath)) |
| 690 | 697 |
| 691 def pack(self, options, args, file_list): | 698 def pack(self, options, args, file_list): |
| 692 """Generates a patch file which can be applied to the root of the | 699 """Generates a patch file which can be applied to the root of the |
| 693 repository.""" | 700 repository.""" |
| 694 path = os.path.join(self._root_dir, self.relpath) | 701 path = os.path.join(self._root_dir, self.relpath) |
| 702 if not os.path.isdir(path): |
| 703 raise gclient_utils.Error('Directory %s is not present.' % path) |
| 695 command = ['diff'] | 704 command = ['diff'] |
| 696 command.extend(args) | 705 command.extend(args) |
| 697 | 706 |
| 698 filterer = DiffFilterer(self.relpath) | 707 filterer = DiffFilterer(self.relpath) |
| 699 scm.SVN.RunAndFilterOutput(command, path, False, False, filterer.Filter) | 708 scm.SVN.RunAndFilterOutput(command, path, False, False, filterer.Filter) |
| 700 | 709 |
| 701 def update(self, options, args, file_list): | 710 def update(self, options, args, file_list): |
| 702 """Runs svn to update or transparently checkout the working copy. | 711 """Runs svn to update or transparently checkout the working copy. |
| 703 | 712 |
| 704 All updated files will be appended to file_list. | 713 All updated files will be appended to file_list. |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 919 command should be a list of strings that represents an svn command. | 928 command should be a list of strings that represents an svn command. |
| 920 | 929 |
| 921 This method returns a new list to be used as a command.""" | 930 This method returns a new list to be used as a command.""" |
| 922 new_command = command[:] | 931 new_command = command[:] |
| 923 if revision: | 932 if revision: |
| 924 new_command.extend(['--revision', str(revision).strip()]) | 933 new_command.extend(['--revision', str(revision).strip()]) |
| 925 # --force was added to 'svn update' in svn 1.5. | 934 # --force was added to 'svn update' in svn 1.5. |
| 926 if options.force and scm.SVN.AssertVersion("1.5")[0]: | 935 if options.force and scm.SVN.AssertVersion("1.5")[0]: |
| 927 new_command.append('--force') | 936 new_command.append('--force') |
| 928 return new_command | 937 return new_command |
| OLD | NEW |