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 |