Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 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 | 5 |
| 6 """Client-side script to send a try job to the try server. It communicates to | 6 """Client-side script to send a try job to the try server. It communicates to |
| 7 the try server by either writting to a svn repository or by directly connecting | 7 the try server by either writting to a svn repository or by directly connecting |
| 8 to the server by HTTP. | 8 to the server by HTTP. |
| 9 """ | 9 """ |
| 10 | 10 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 84 return self.args[0] + '\n' + HELP_STRING | 84 return self.args[0] + '\n' + HELP_STRING |
| 85 | 85 |
| 86 | 86 |
| 87 def Escape(name): | 87 def Escape(name): |
| 88 """Escapes characters that could interfere with the file system or try job | 88 """Escapes characters that could interfere with the file system or try job |
| 89 parsing. | 89 parsing. |
| 90 """ | 90 """ |
| 91 return re.sub(r'[^\w#-]', '_', name) | 91 return re.sub(r'[^\w#-]', '_', name) |
| 92 | 92 |
| 93 | 93 |
| 94 def _FindRepoCheckoutRoot(path): | |
| 95 """Find the equivalent of gclient root of a repo-managed directory. | |
| 96 | |
| 97 Assumes the equivalent of gclient root is a level below the repo root. | |
| 98 | |
| 99 Args: | |
| 100 path: A path that is within the repo-managed directory. | |
| 101 """ | |
| 102 path = os.path.abspath(path) | |
| 103 while True: | |
| 104 if path == os.path.dirname(path): | |
| 105 break | |
| 106 if os.path.isdir(os.path.join(os.path.dirname(path), '.repo')): | |
| 107 return path | |
| 108 path = os.path.dirname(path) | |
| 109 return None | |
| 110 | |
| 111 | |
| 94 class SCM(object): | 112 class SCM(object): |
| 95 """Simplistic base class to implement one function: ProcessOptions.""" | 113 """Simplistic base class to implement one function: ProcessOptions.""" |
| 96 def __init__(self, options, path, file_list): | 114 def __init__(self, options, path, file_list): |
| 97 items = path.split('@') | 115 items = path.split('@') |
| 98 assert len(items) <= 2 | 116 assert len(items) <= 2 |
| 99 self.checkout_root = items[0] | 117 self.checkout_root = os.path.abspath(items[0]) |
| 100 items.append(None) | 118 items.append(None) |
| 101 self.diff_against = items[1] | 119 self.diff_against = items[1] |
| 102 self.options = options | 120 self.options = options |
| 103 # Lazy-load file list from the SCM unless files were specified in options. | 121 # Lazy-load file list from the SCM unless files were specified in options. |
| 104 self._files = None | 122 self._files = None |
| 105 self._file_tuples = None | 123 self._file_tuples = None |
| 106 if file_list: | 124 if file_list: |
| 107 self._files = file_list | 125 self._files = file_list |
| 108 self._file_tuples = [('M', f) for f in self.files] | 126 self._file_tuples = [('M', f) for f in self.files] |
| 109 self.options.files = None | 127 self.options.files = None |
| 110 self.codereview_settings = None | 128 self.codereview_settings = None |
| 111 self.codereview_settings_file = 'codereview.settings' | 129 self.codereview_settings_file = 'codereview.settings' |
| 112 self.gclient_root = None | 130 self.toplevel_root = None |
| 113 | 131 |
| 114 def GetFileNames(self): | 132 def GetFileNames(self): |
| 115 """Return the list of files in the diff.""" | 133 """Return the list of files in the diff.""" |
| 116 return self.files | 134 return self.files |
| 117 | 135 |
| 118 def GetCodeReviewSetting(self, key): | 136 def GetCodeReviewSetting(self, key): |
| 119 """Returns a value for the given key for this repository. | 137 """Returns a value for the given key for this repository. |
| 120 | 138 |
| 121 Uses gcl-style settings from the repository. | 139 Uses gcl-style settings from the repository. |
| 122 """ | 140 """ |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 145 'project': self.GetCodeReviewSetting('TRYSERVER_PROJECT'), | 163 'project': self.GetCodeReviewSetting('TRYSERVER_PROJECT'), |
| 146 'root': self.GetCodeReviewSetting('TRYSERVER_ROOT'), | 164 'root': self.GetCodeReviewSetting('TRYSERVER_ROOT'), |
| 147 'patchlevel': self.GetCodeReviewSetting('TRYSERVER_PATCHLEVEL'), | 165 'patchlevel': self.GetCodeReviewSetting('TRYSERVER_PATCHLEVEL'), |
| 148 } | 166 } |
| 149 logging.info('\n'.join(['%s: %s' % (k, v) | 167 logging.info('\n'.join(['%s: %s' % (k, v) |
| 150 for (k, v) in settings.iteritems() if v])) | 168 for (k, v) in settings.iteritems() if v])) |
| 151 for (k, v) in settings.iteritems(): | 169 for (k, v) in settings.iteritems(): |
| 152 if v and getattr(self.options, k) is None: | 170 if v and getattr(self.options, k) is None: |
| 153 setattr(self.options, k, v) | 171 setattr(self.options, k, v) |
| 154 | 172 |
| 155 def _GclientStyleSettings(self): | |
| 156 """Find the root, assuming a gclient-style checkout.""" | |
| 157 if not self.options.no_gclient and not self.options.root: | |
| 158 root = self.checkout_root | |
| 159 self.gclient_root = gclient_utils.FindGclientRoot(root) | |
| 160 if self.gclient_root: | |
| 161 logging.info('Found .gclient at %s' % self.gclient_root) | |
| 162 self.options.root = gclient_utils.PathDifference(self.gclient_root, | |
| 163 root) | |
| 164 | |
| 165 def AutomagicalSettings(self): | 173 def AutomagicalSettings(self): |
| 166 """Determines settings based on supported code review and checkout tools. | 174 """Determines settings based on supported code review and checkout tools. |
| 167 """ | 175 """ |
| 168 self._GclientStyleSettings() | 176 # Try to find gclient root first. |
| 177 if not self.options.no_gclient: | |
|
M-A Ruel
2011/10/11 19:50:36
I feel like --no_gclient should also affect the se
| |
| 178 self.toplevel_root = gclient_utils.FindGclientRoot(self.checkout_root) | |
| 179 if self.toplevel_root: | |
| 180 logging.info('Found .gclient at %s' % self.toplevel_root) | |
| 181 | |
| 182 # If no gclient toplevel root found, treat it like a repo-managed checkout. | |
| 183 if not self.toplevel_root: | |
| 184 self.toplevel_root = _FindRepoCheckoutRoot(self.checkout_root) | |
| 185 if self.toplevel_root: | |
| 186 logging.info('Found .repo dir at %s' | |
| 187 % os.path.dirname(self.toplevel_root)) | |
| 188 | |
| 189 assert os.path.abspath(self.toplevel_root) == self.toplevel_root | |
| 190 if self.toplevel_root and not self.options.root: | |
| 191 self.options.root = gclient_utils.PathDifference(self.toplevel_root, | |
|
M-A Ruel
2011/10/11 19:50:36
It's needed? I feel like it's a bug. :/
| |
| 192 self.checkout_root) | |
| 193 | |
| 169 self._GclStyleSettings() | 194 self._GclStyleSettings() |
| 170 | 195 |
| 171 def ReadRootFile(self, filename): | 196 def ReadRootFile(self, filename): |
| 172 if not self.options.root: | 197 root = cur = self.checkout_root |
| 173 filepath = os.path.join(self.checkout_root, filename) | 198 if self.toplevel_root: |
|
M-A Ruel
2011/10/11 19:50:36
cur = self.checkout_root
root = self.toplevel_root
rcui1
2011/10/11 21:26:49
Done.
| |
| 174 if os.path.isfile(filepath): | 199 root = self.toplevel_root |
| 175 logging.info('Found %s at %s' % (filename, self.checkout_root)) | 200 |
| 176 return gclient_utils.FileRead(filepath) | |
| 177 return None | |
| 178 cur = os.path.abspath(self.checkout_root) | |
| 179 if self.gclient_root: | |
| 180 root = os.path.abspath(self.gclient_root) | |
| 181 else: | |
| 182 root = gclient_utils.FindGclientRoot(cur) | |
| 183 if not root: | |
| 184 root = cur | |
| 185 assert cur.startswith(root), (root, cur) | 201 assert cur.startswith(root), (root, cur) |
| 186 while cur.startswith(root): | 202 while cur.startswith(root): |
| 187 filepath = os.path.join(cur, filename) | 203 filepath = os.path.join(cur, filename) |
| 188 if os.path.isfile(filepath): | 204 if os.path.isfile(filepath): |
| 189 logging.info('Found %s at %s' % (filename, cur)) | 205 logging.info('Found %s at %s' % (filename, cur)) |
| 190 return gclient_utils.FileRead(filepath) | 206 return gclient_utils.FileRead(filepath) |
| 191 cur = os.path.dirname(cur) | 207 cur = os.path.dirname(cur) |
| 192 logging.warning('Didn\'t find %s' % filename) | 208 logging.warning('Didn\'t find %s' % filename) |
| 193 return None | 209 return None |
| 194 | 210 |
| (...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 809 return 1 | 825 return 1 |
| 810 except (gclient_utils.Error, subprocess2.CalledProcessError), e: | 826 except (gclient_utils.Error, subprocess2.CalledProcessError), e: |
| 811 print >> sys.stderr, e | 827 print >> sys.stderr, e |
| 812 return 1 | 828 return 1 |
| 813 return 0 | 829 return 0 |
| 814 | 830 |
| 815 | 831 |
| 816 if __name__ == "__main__": | 832 if __name__ == "__main__": |
| 817 fix_encoding.fix_encoding() | 833 fix_encoding.fix_encoding() |
| 818 sys.exit(TryChange(None, None, False)) | 834 sys.exit(TryChange(None, None, False)) |
| OLD | NEW |