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 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 class SCM(object): | 94 class SCM(object): |
95 """Simplistic base class to implement one function: ProcessOptions.""" | 95 """Simplistic base class to implement one function: ProcessOptions.""" |
96 def __init__(self, options, path, file_list): | 96 def __init__(self, options, path, file_list): |
97 items = path.split('@') | 97 items = path.split('@') |
98 assert len(items) <= 2 | 98 assert len(items) <= 2 |
99 self.checkout_root = items[0] | 99 self.checkout_root = os.path.abspath(items[0]) |
100 items.append(None) | 100 items.append(None) |
101 self.diff_against = items[1] | 101 self.diff_against = items[1] |
102 self.options = options | 102 self.options = options |
103 # Lazy-load file list from the SCM unless files were specified in options. | 103 # Lazy-load file list from the SCM unless files were specified in options. |
104 self._files = None | 104 self._files = None |
105 self._file_tuples = None | 105 self._file_tuples = None |
106 if file_list: | 106 if file_list: |
107 self._files = file_list | 107 self._files = file_list |
108 self._file_tuples = [('M', f) for f in self.files] | 108 self._file_tuples = [('M', f) for f in self.files] |
109 self.options.files = None | 109 self.options.files = None |
110 self.codereview_settings = None | 110 self.codereview_settings = None |
111 self.codereview_settings_file = 'codereview.settings' | 111 self.codereview_settings_file = 'codereview.settings' |
112 self.gclient_root = None | 112 self.toplevel_root = None |
113 | 113 |
114 def GetFileNames(self): | 114 def GetFileNames(self): |
115 """Return the list of files in the diff.""" | 115 """Return the list of files in the diff.""" |
116 return self.files | 116 return self.files |
117 | 117 |
118 def GetCodeReviewSetting(self, key): | 118 def GetCodeReviewSetting(self, key): |
119 """Returns a value for the given key for this repository. | 119 """Returns a value for the given key for this repository. |
120 | 120 |
121 Uses gcl-style settings from the repository. | 121 Uses gcl-style settings from the repository. |
122 """ | 122 """ |
(...skipping 22 matching lines...) Expand all Loading... |
145 'project': self.GetCodeReviewSetting('TRYSERVER_PROJECT'), | 145 'project': self.GetCodeReviewSetting('TRYSERVER_PROJECT'), |
146 'root': self.GetCodeReviewSetting('TRYSERVER_ROOT'), | 146 'root': self.GetCodeReviewSetting('TRYSERVER_ROOT'), |
147 'patchlevel': self.GetCodeReviewSetting('TRYSERVER_PATCHLEVEL'), | 147 'patchlevel': self.GetCodeReviewSetting('TRYSERVER_PATCHLEVEL'), |
148 } | 148 } |
149 logging.info('\n'.join(['%s: %s' % (k, v) | 149 logging.info('\n'.join(['%s: %s' % (k, v) |
150 for (k, v) in settings.iteritems() if v])) | 150 for (k, v) in settings.iteritems() if v])) |
151 for (k, v) in settings.iteritems(): | 151 for (k, v) in settings.iteritems(): |
152 if v and getattr(self.options, k) is None: | 152 if v and getattr(self.options, k) is None: |
153 setattr(self.options, k, v) | 153 setattr(self.options, k, v) |
154 | 154 |
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): | 155 def AutomagicalSettings(self): |
166 """Determines settings based on supported code review and checkout tools. | 156 """Determines settings based on supported code review and checkout tools. |
167 """ | 157 """ |
168 self._GclientStyleSettings() | 158 # Try to find gclient or repo root first. |
| 159 if not self.options.no_search: |
| 160 self.toplevel_root = gclient_utils.FindGclientRoot(self.checkout_root) |
| 161 if self.toplevel_root: |
| 162 logging.info('Found .gclient at %s' % self.toplevel_root) |
| 163 else: |
| 164 self.toplevel_root = gclient_utils.FindFileUpwards( |
| 165 os.path.join('..', '.repo'), self.checkout_root) |
| 166 if self.toplevel_root: |
| 167 logging.info('Found .repo dir at %s' |
| 168 % os.path.dirname(self.toplevel_root)) |
| 169 |
| 170 if self.toplevel_root and not self.options.root: |
| 171 assert os.path.abspath(self.toplevel_root) == self.toplevel_root |
| 172 self.options.root = gclient_utils.PathDifference(self.toplevel_root, |
| 173 self.checkout_root) |
| 174 |
169 self._GclStyleSettings() | 175 self._GclStyleSettings() |
170 | 176 |
171 def ReadRootFile(self, filename): | 177 def ReadRootFile(self, filename): |
172 if not self.options.root: | 178 cur = self.checkout_root |
173 filepath = os.path.join(self.checkout_root, filename) | 179 root = self.toplevel_root or self.checkout_root |
174 if os.path.isfile(filepath): | 180 |
175 logging.info('Found %s at %s' % (filename, self.checkout_root)) | |
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) | 181 assert cur.startswith(root), (root, cur) |
186 while cur.startswith(root): | 182 while cur.startswith(root): |
187 filepath = os.path.join(cur, filename) | 183 filepath = os.path.join(cur, filename) |
188 if os.path.isfile(filepath): | 184 if os.path.isfile(filepath): |
189 logging.info('Found %s at %s' % (filename, cur)) | 185 logging.info('Found %s at %s' % (filename, cur)) |
190 return gclient_utils.FileRead(filepath) | 186 return gclient_utils.FileRead(filepath) |
191 cur = os.path.dirname(cur) | 187 cur = os.path.dirname(cur) |
192 logging.warning('Didn\'t find %s' % filename) | 188 logging.warning('Didn\'t find %s' % filename) |
193 return None | 189 return None |
194 | 190 |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 help="Used as -pN parameter to patch") | 583 help="Used as -pN parameter to patch") |
588 group.add_option("-s", "--sub_rep", action="append", default=[], | 584 group.add_option("-s", "--sub_rep", action="append", default=[], |
589 help="Subcheckout to use in addition. This is mainly " | 585 help="Subcheckout to use in addition. This is mainly " |
590 "useful for gclient-style checkouts. In git, checkout " | 586 "useful for gclient-style checkouts. In git, checkout " |
591 "the branch with changes first. Use @rev or " | 587 "the branch with changes first. Use @rev or " |
592 "@branch to specify the " | 588 "@branch to specify the " |
593 "revision/branch to diff against. If no @branch is " | 589 "revision/branch to diff against. If no @branch is " |
594 "given the diff will be against the upstream branch. " | 590 "given the diff will be against the upstream branch. " |
595 "If @branch then the diff is branch..HEAD. " | 591 "If @branch then the diff is branch..HEAD. " |
596 "All edits must be checked in.") | 592 "All edits must be checked in.") |
597 group.add_option("--no_gclient", action="store_true", | 593 group.add_option("--no_search", action="store_true", |
598 help="Disable automatic search for gclient checkout.") | 594 help=("Disable automatic search for gclient or repo " |
| 595 "checkout root.")) |
599 group.add_option("-E", "--exclude", action="append", | 596 group.add_option("-E", "--exclude", action="append", |
600 default=['ChangeLog'], metavar='REGEXP', | 597 default=['ChangeLog'], metavar='REGEXP', |
601 help="Regexp patterns to exclude files. Default: %default") | 598 help="Regexp patterns to exclude files. Default: %default") |
602 group.add_option("--upstream_branch", action="store", | 599 group.add_option("--upstream_branch", action="store", |
603 help="Specify the upstream branch to diff against in the " | 600 help="Specify the upstream branch to diff against in the " |
604 "main checkout") | 601 "main checkout") |
605 parser.add_option_group(group) | 602 parser.add_option_group(group) |
606 | 603 |
607 group = optparse.OptionGroup(parser, "Access the try server by HTTP") | 604 group = optparse.OptionGroup(parser, "Access the try server by HTTP") |
608 group.add_option("--use_http", | 605 group.add_option("--use_http", |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 return 1 | 806 return 1 |
810 except (gclient_utils.Error, subprocess2.CalledProcessError), e: | 807 except (gclient_utils.Error, subprocess2.CalledProcessError), e: |
811 print >> sys.stderr, e | 808 print >> sys.stderr, e |
812 return 1 | 809 return 1 |
813 return 0 | 810 return 0 |
814 | 811 |
815 | 812 |
816 if __name__ == "__main__": | 813 if __name__ == "__main__": |
817 fix_encoding.fix_encoding() | 814 fix_encoding.fix_encoding() |
818 sys.exit(TryChange(None, None, False)) | 815 sys.exit(TryChange(None, None, False)) |
OLD | NEW |