OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 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 # Copyright (C) 2008 Evan Martin <martine@danga.com> | 6 # Copyright (C) 2008 Evan Martin <martine@danga.com> |
7 | 7 |
8 """A git-command for integrating reviews on Rietveld.""" | 8 """A git-command for integrating reviews on Rietveld.""" |
9 | 9 |
10 from distutils.version import LooseVersion | 10 from distutils.version import LooseVersion |
(...skipping 2067 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2078 group = optparse.OptionGroup(parser, "Try job options") | 2078 group = optparse.OptionGroup(parser, "Try job options") |
2079 group.add_option( | 2079 group.add_option( |
2080 "-b", "--bot", action="append", | 2080 "-b", "--bot", action="append", |
2081 help=("IMPORTANT: specify ONE builder per --bot flag. Use it multiple " | 2081 help=("IMPORTANT: specify ONE builder per --bot flag. Use it multiple " |
2082 "times to specify multiple builders. ex: " | 2082 "times to specify multiple builders. ex: " |
2083 "'-bwin_rel:ui_tests,webkit_unit_tests -bwin_layout'. See " | 2083 "'-bwin_rel:ui_tests,webkit_unit_tests -bwin_layout'. See " |
2084 "the try server waterfall for the builders name and the tests " | 2084 "the try server waterfall for the builders name and the tests " |
2085 "available. Can also be used to specify gtest_filter, e.g. " | 2085 "available. Can also be used to specify gtest_filter, e.g. " |
2086 "-bwin_rel:base_unittests:ValuesTest.*Value")) | 2086 "-bwin_rel:base_unittests:ValuesTest.*Value")) |
2087 group.add_option( | 2087 group.add_option( |
| 2088 "-m", "--master", default='', |
| 2089 help=("Specify a try master where to run the tries.")) |
| 2090 group.add_option( |
2088 "-r", "--revision", | 2091 "-r", "--revision", |
2089 help="Revision to use for the try job; default: the " | 2092 help="Revision to use for the try job; default: the " |
2090 "revision will be determined by the try server; see " | 2093 "revision will be determined by the try server; see " |
2091 "its waterfall for more info") | 2094 "its waterfall for more info") |
2092 group.add_option( | 2095 group.add_option( |
2093 "-c", "--clobber", action="store_true", default=False, | 2096 "-c", "--clobber", action="store_true", default=False, |
2094 help="Force a clobber before building; e.g. don't do an " | 2097 help="Force a clobber before building; e.g. don't do an " |
2095 "incremental build") | 2098 "incremental build") |
2096 group.add_option( | 2099 group.add_option( |
2097 "--project", | 2100 "--project", |
(...skipping 12 matching lines...) Expand all Loading... |
2110 if args: | 2113 if args: |
2111 parser.error('Unknown arguments: %s' % args) | 2114 parser.error('Unknown arguments: %s' % args) |
2112 | 2115 |
2113 cl = Changelist() | 2116 cl = Changelist() |
2114 if not cl.GetIssue(): | 2117 if not cl.GetIssue(): |
2115 parser.error('Need to upload first') | 2118 parser.error('Need to upload first') |
2116 | 2119 |
2117 if not options.name: | 2120 if not options.name: |
2118 options.name = cl.GetBranch() | 2121 options.name = cl.GetBranch() |
2119 | 2122 |
2120 # Process --bot and --testfilter. | 2123 def GetMasterMap(): |
2121 if not options.bot: | 2124 # Process --bot and --testfilter. |
2122 # Get try slaves from PRESUBMIT.py files if not specified. | 2125 if not options.bot: |
2123 change = cl.GetChange(cl.GetCommonAncestorWithUpstream(), None) | 2126 change = cl.GetChange(cl.GetCommonAncestorWithUpstream(), None) |
2124 options.bot = presubmit_support.DoGetTrySlaves( | |
2125 change, | |
2126 change.LocalPaths(), | |
2127 settings.GetRoot(), | |
2128 None, | |
2129 None, | |
2130 options.verbose, | |
2131 sys.stdout) | |
2132 if not options.bot: | |
2133 parser.error('No default try builder to try, use --bot') | |
2134 | 2127 |
2135 builders_and_tests = {} | 2128 # Get try masters from PRESUBMIT.py files. |
2136 old_style = filter(lambda x: isinstance(x, basestring), options.bot) | 2129 masters = presubmit_support.DoGetTryMasters( |
2137 new_style = filter(lambda x: isinstance(x, tuple), options.bot) | 2130 change, |
| 2131 change.LocalPaths(), |
| 2132 settings.GetRoot(), |
| 2133 None, |
| 2134 None, |
| 2135 options.verbose, |
| 2136 sys.stdout) |
| 2137 if masters: |
| 2138 return masters |
2138 | 2139 |
2139 for bot in old_style: | 2140 # Fall back to deprecated method: get try slaves from PRESUBMIT.py files. |
2140 if ':' in bot: | 2141 options.bot = presubmit_support.DoGetTrySlaves( |
2141 builder, tests = bot.split(':', 1) | 2142 change, |
2142 builders_and_tests.setdefault(builder, []).extend(tests.split(',')) | 2143 change.LocalPaths(), |
2143 elif ',' in bot: | 2144 settings.GetRoot(), |
2144 parser.error('Specify one bot per --bot flag') | 2145 None, |
2145 else: | 2146 None, |
2146 builders_and_tests.setdefault(bot, []).append('defaulttests') | 2147 options.verbose, |
| 2148 sys.stdout) |
| 2149 if not options.bot: |
| 2150 parser.error('No default try builder to try, use --bot') |
2147 | 2151 |
2148 for bot, tests in new_style: | 2152 builders_and_tests = {} |
2149 builders_and_tests.setdefault(bot, []).extend(tests) | 2153 # TODO(machenbach): The old style command-line options don't support |
| 2154 # multiple try masters yet. |
| 2155 old_style = filter(lambda x: isinstance(x, basestring), options.bot) |
| 2156 new_style = filter(lambda x: isinstance(x, tuple), options.bot) |
| 2157 |
| 2158 for bot in old_style: |
| 2159 if ':' in bot: |
| 2160 builder, tests = bot.split(':', 1) |
| 2161 builders_and_tests.setdefault(builder, []).extend(tests.split(',')) |
| 2162 elif ',' in bot: |
| 2163 parser.error('Specify one bot per --bot flag') |
| 2164 else: |
| 2165 builders_and_tests.setdefault(bot, []).append('defaulttests') |
| 2166 |
| 2167 for bot, tests in new_style: |
| 2168 builders_and_tests.setdefault(bot, []).extend(tests) |
| 2169 |
| 2170 # Return a master map with one master to be backwards compatible. The |
| 2171 # master name defaults to an empty string, which will cause the master |
| 2172 # not to be set on rietveld (deprecated). |
| 2173 return {options.master: builders_and_tests} |
| 2174 |
| 2175 masters = GetMasterMap() |
2150 | 2176 |
2151 if options.testfilter: | 2177 if options.testfilter: |
2152 forced_tests = sum((t.split(',') for t in options.testfilter), []) | 2178 forced_tests = sum((t.split(',') for t in options.testfilter), []) |
2153 builders_and_tests = dict( | 2179 masters = dict((master, dict( |
2154 (b, forced_tests) for b, t in builders_and_tests.iteritems() | 2180 (b, forced_tests) for b, t in slaves.iteritems() |
2155 if t != ['compile']) | 2181 if t != ['compile'])) for master, slaves in masters.iteritems()) |
2156 | 2182 |
2157 if any('triggered' in b for b in builders_and_tests): | 2183 for builders in masters.itervalues(): |
2158 print >> sys.stderr, ( | 2184 if any('triggered' in b for b in builders): |
2159 'ERROR You are trying to send a job to a triggered bot. This type of' | 2185 print >> sys.stderr, ( |
2160 ' bot requires an\ninitial job from a parent (usually a builder). ' | 2186 'ERROR You are trying to send a job to a triggered bot. This type of' |
2161 'Instead send your job to the parent.\n' | 2187 ' bot requires an\ninitial job from a parent (usually a builder). ' |
2162 'Bot list: %s' % builders_and_tests) | 2188 'Instead send your job to the parent.\n' |
2163 return 1 | 2189 'Bot list: %s' % builders) |
| 2190 return 1 |
2164 | 2191 |
2165 patchset = cl.GetMostRecentPatchset() | 2192 patchset = cl.GetMostRecentPatchset() |
2166 if patchset and patchset != cl.GetPatchset(): | 2193 if patchset and patchset != cl.GetPatchset(): |
2167 print( | 2194 print( |
2168 '\nWARNING Mismatch between local config and server. Did a previous ' | 2195 '\nWARNING Mismatch between local config and server. Did a previous ' |
2169 'upload fail?\ngit-cl try always uses latest patchset from rietveld. ' | 2196 'upload fail?\ngit-cl try always uses latest patchset from rietveld. ' |
2170 'Continuing using\npatchset %s.\n' % patchset) | 2197 'Continuing using\npatchset %s.\n' % patchset) |
2171 try: | 2198 try: |
2172 cl.RpcServer().trigger_try_jobs( | 2199 cl.RpcServer().trigger_distributed_try_jobs( |
2173 cl.GetIssue(), patchset, options.name, options.clobber, | 2200 cl.GetIssue(), patchset, options.name, options.clobber, |
2174 options.revision, builders_and_tests) | 2201 options.revision, masters) |
2175 except urllib2.HTTPError, e: | 2202 except urllib2.HTTPError, e: |
2176 if e.code == 404: | 2203 if e.code == 404: |
2177 print('404 from rietveld; ' | 2204 print('404 from rietveld; ' |
2178 'did you mean to use "git try" instead of "git cl try"?') | 2205 'did you mean to use "git try" instead of "git cl try"?') |
2179 return 1 | 2206 return 1 |
2180 print('Tried jobs on:') | 2207 print('Tried jobs on:') |
2181 length = max(len(builder) for builder in builders_and_tests) | 2208 |
2182 for builder in sorted(builders_and_tests): | 2209 for (master, builders) in masters.iteritems(): |
2183 print ' %*s: %s' % (length, builder, ','.join(builders_and_tests[builder])) | 2210 if master: |
| 2211 print 'Master: %s' % master |
| 2212 length = max(len(builder) for builder in builders) |
| 2213 for builder in sorted(builders): |
| 2214 print ' %*s: %s' % (length, builder, ','.join(builders[builder])) |
2184 return 0 | 2215 return 0 |
2185 | 2216 |
2186 | 2217 |
2187 @subcommand.usage('[new upstream branch]') | 2218 @subcommand.usage('[new upstream branch]') |
2188 def CMDupstream(parser, args): | 2219 def CMDupstream(parser, args): |
2189 """Prints or sets the name of the upstream branch, if any.""" | 2220 """Prints or sets the name of the upstream branch, if any.""" |
2190 _, args = parser.parse_args(args) | 2221 _, args = parser.parse_args(args) |
2191 if len(args) > 1: | 2222 if len(args) > 1: |
2192 parser.error('Unrecognized args: %s' % ' '.join(args)) | 2223 parser.error('Unrecognized args: %s' % ' '.join(args)) |
2193 | 2224 |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2430 ('AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' | 2461 ('AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' |
2431 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) | 2462 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) |
2432 | 2463 |
2433 | 2464 |
2434 if __name__ == '__main__': | 2465 if __name__ == '__main__': |
2435 # These affect sys.stdout so do it outside of main() to simplify mocks in | 2466 # These affect sys.stdout so do it outside of main() to simplify mocks in |
2436 # unit testing. | 2467 # unit testing. |
2437 fix_encoding.fix_encoding() | 2468 fix_encoding.fix_encoding() |
2438 colorama.init() | 2469 colorama.init() |
2439 sys.exit(main(sys.argv[1:])) | 2470 sys.exit(main(sys.argv[1:])) |
OLD | NEW |