OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2009 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2009 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 """Client-side script to send a try job to the try server. It communicates to | 5 """Client-side script to send a try job to the try server. It communicates to |
6 the try server by either writting to a svn repository or by directly connecting | 6 the try server by either writting to a svn repository or by directly connecting |
7 to the server by HTTP. | 7 to the server by HTTP. |
8 """ | 8 """ |
9 | 9 |
10 import datetime | 10 import datetime |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 if not self.options.email: | 92 if not self.options.email: |
93 # Assumes the svn credential is an email address. | 93 # Assumes the svn credential is an email address. |
94 self.options.email = scm.SVN.GetEmail(self.checkout_root) | 94 self.options.email = scm.SVN.GetEmail(self.checkout_root) |
95 | 95 |
96 def _GenerateDiff(self): | 96 def _GenerateDiff(self): |
97 """Returns a string containing the diff for the given file list. | 97 """Returns a string containing the diff for the given file list. |
98 | 98 |
99 The files in the list should either be absolute paths or relative to the | 99 The files in the list should either be absolute paths or relative to the |
100 given root. | 100 given root. |
101 """ | 101 """ |
102 previous_cwd = os.getcwd() | |
103 os.chdir(self.checkout_root) | |
104 if not self.options.files: | 102 if not self.options.files: |
105 self.options.files = [f[1] for f in scm.SVN.CaptureStatus(None)] | 103 previous_cwd = os.getcwd() |
106 # Directories will return None so filter them out. | 104 os.chdir(self.checkout_root) |
107 diff = filter(None, [scm.SVN.DiffItem(f) for f in self.options.files]) | 105 excluded = ['!', '?', 'X', ' ', '~'] |
108 os.chdir(previous_cwd) | 106 self.options.files = [ |
109 return "".join(diff) | 107 f[1] for f in scm.SVN.CaptureStatus(self.checkout_root) |
| 108 if f[0][0] not in excluded |
| 109 ] |
| 110 os.chdir(previous_cwd) |
| 111 return scm.SVN.GenerateDiff(self.options.files, full_move=True) |
110 | 112 |
111 def GetLocalRoot(self): | 113 def GetLocalRoot(self): |
112 """Return the path of the repository root.""" | 114 """Return the path of the repository root.""" |
113 return self.checkout_root | 115 return self.checkout_root |
114 | 116 |
115 def GetBots(self): | 117 def GetBots(self): |
116 try: | 118 try: |
117 import gcl | 119 import gcl |
118 return gcl.GetCachedFile('PRESUBMIT.py', use_root=True) | 120 return gcl.GetCachedFile('PRESUBMIT.py', use_root=True) |
119 except ImportError: | 121 except ImportError: |
120 try: | 122 try: |
121 return gclient_utils.FileRead(os.path.join(self.checkout_root, | 123 return gclient_utils.FileRead(os.path.join(self.checkout_root, |
122 'PRESUBMIT.py')) | 124 'PRESUBMIT.py')) |
123 except OSError: | 125 except (IOError, OSError): |
124 return None | 126 return None |
125 | 127 |
126 | 128 |
127 class GIT(SCM): | 129 class GIT(SCM): |
128 """Gathers the options and diff for a git checkout.""" | 130 """Gathers the options and diff for a git checkout.""" |
129 def __init__(self, *args, **kwargs): | 131 def __init__(self, *args, **kwargs): |
130 SCM.__init__(self, *args, **kwargs) | 132 SCM.__init__(self, *args, **kwargs) |
131 self.checkout_root = os.path.abspath( | 133 self.checkout_root = os.path.abspath( |
132 gclient_utils.CheckCall(['git', 'rev-parse', '--show-cdup']).strip()) | 134 gclient_utils.CheckCall(['git', 'rev-parse', '--show-cdup']).strip()) |
133 if not self.options.diff: | 135 if not self.options.diff: |
134 self.options.diff = self._GenerateDiff() | 136 self.options.diff = self._GenerateDiff() |
135 if not self.options.name: | 137 if not self.options.name: |
136 self.options.name = self._GetPatchName() | 138 self.options.name = self._GetPatchName() |
137 if not self.options.email: | 139 if not self.options.email: |
138 self.options.email = scm.GIT.GetEmail('.') | 140 self.options.email = scm.GIT.GetEmail('.') |
139 | 141 |
140 def _GenerateDiff(self): | 142 def _GenerateDiff(self): |
141 """Get the diff we'll send to the try server. We ignore the files list.""" | 143 """Get the diff we'll send to the try server. We ignore the files list.""" |
142 branch = gclient_utils.CheckCall(['git', 'cl', 'upstream']).strip() | 144 return scm.GIT.GenerateDiff(self.checkout_root) |
143 diff = gclient_utils.CheckCall(['git', 'diff-tree', '-p', '--no-prefix', | |
144 branch, 'HEAD']).splitlines(True) | |
145 for i in range(len(diff)): | |
146 # In the case of added files, replace /dev/null with the path to the | |
147 # file being added. | |
148 if diff[i].startswith('--- /dev/null'): | |
149 diff[i] = '--- %s' % diff[i+1][4:] | |
150 return ''.join(diff) | |
151 | 145 |
152 def _GetPatchName(self): | 146 def _GetPatchName(self): |
153 """Construct a name for this patch.""" | 147 """Construct a name for this patch.""" |
154 # TODO: perhaps include the hash of the current commit, to distinguish | 148 # TODO: perhaps include the hash of the current commit, to distinguish |
155 # patches? | 149 # patches? |
156 branch = gclient_utils.CheckCall(['git', 'symbolic-ref', 'HEAD']).strip() | 150 branch = gclient_utils.CheckCall(['git', 'symbolic-ref', 'HEAD']).strip() |
157 if not branch.startswith('refs/heads/'): | 151 if not branch.startswith('refs/heads/'): |
158 # TODO(maruel): Find a better type. | 152 # TODO(maruel): Find a better type. |
159 raise NoTryServerAccess("Couldn't figure out branch name") | 153 raise NoTryServerAccess("Couldn't figure out branch name") |
160 branch = branch[len('refs/heads/'):] | 154 branch = branch[len('refs/heads/'):] |
161 return branch | 155 return branch |
162 | 156 |
163 def GetLocalRoot(self): | 157 def GetLocalRoot(self): |
164 """Return the path of the repository root.""" | 158 """Return the path of the repository root.""" |
165 return self.checkout_root | 159 return self.checkout_root |
166 | 160 |
167 def GetBots(self): | 161 def GetBots(self): |
168 try: | 162 try: |
169 return gclient_utils.FileRead(os.path.join(self.checkout_root, | 163 return gclient_utils.FileRead(os.path.join(self.checkout_root, |
170 'PRESUBMIT.py')) | 164 'PRESUBMIT.py')) |
171 except OSError: | 165 except (IOError, OSError): |
172 return None | 166 return None |
173 | 167 |
174 | 168 |
175 def _ParseSendChangeOptions(options): | 169 def _ParseSendChangeOptions(options): |
176 """Parse common options passed to _SendChangeHTTP and _SendChangeSVN.""" | 170 """Parse common options passed to _SendChangeHTTP and _SendChangeSVN.""" |
177 values = {} | 171 values = {} |
178 if options.email: | 172 if options.email: |
179 values['email'] = options.email | 173 values['email'] = options.email |
180 values['user'] = options.user | 174 values['user'] = options.user |
181 values['name'] = options.name | 175 values['name'] = options.name |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 except (InvalidScript, NoTryServerAccess), e: | 493 except (InvalidScript, NoTryServerAccess), e: |
500 if swallow_exception: | 494 if swallow_exception: |
501 return 1 | 495 return 1 |
502 print e | 496 print e |
503 return 1 | 497 return 1 |
504 return 0 | 498 return 0 |
505 | 499 |
506 | 500 |
507 if __name__ == "__main__": | 501 if __name__ == "__main__": |
508 sys.exit(TryChange(None, [], False)) | 502 sys.exit(TryChange(None, [], False)) |
OLD | NEW |