Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: tools/mb/mb.py

Issue 1832093003: Fix MB and running mash browser_tests under swarming (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: patch for review Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « testing/buildbot/gn_isolate_map.pyl ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2015 The Chromium Authors. All rights reserved. 2 # Copyright 2015 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 """MB - the Meta-Build wrapper around GYP and GN 6 """MB - the Meta-Build wrapper around GYP and GN
7 7
8 MB is a wrapper script for GYP and GN that can be used to generate build files 8 MB is a wrapper script for GYP and GN that can be used to generate build files
9 for sets of canned configurations and analyze them. 9 for sets of canned configurations and analyze them.
10 """ 10 """
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 subp.add_argument('target', nargs=1, 118 subp.add_argument('target', nargs=1,
119 help='ninja target to generate the isolate for') 119 help='ninja target to generate the isolate for')
120 subp.set_defaults(func=self.CmdIsolate) 120 subp.set_defaults(func=self.CmdIsolate)
121 121
122 subp = subps.add_parser('lookup', 122 subp = subps.add_parser('lookup',
123 help='look up the command for a given config or ' 123 help='look up the command for a given config or '
124 'builder') 124 'builder')
125 AddCommonOptions(subp) 125 AddCommonOptions(subp)
126 subp.set_defaults(func=self.CmdLookup) 126 subp.set_defaults(func=self.CmdLookup)
127 127
128 subp = subps.add_parser('run', 128 subp = subps.add_parser(
129 help='build and run the isolated version of a ' 129 'run',
130 'binary') 130 help='build and run the isolated version of a '
131 'binary',
132 formatter_class=argparse.RawDescriptionHelpFormatter)
133 subp.description = (
134 'Build, isolate, and run the given binary with the command line\n'
135 'listed in the isolate. You may pass extra arguments after the\n'
136 'target; use "--" if the extra arguments need to include switches.\n'
137 '\n'
138 'Examples:\n'
139 '\n'
140 ' % tools/mb/mb.py run -m chromium.linux -b "Linux Builder" \\\n'
141 ' //out/Default content_browsertests\n'
142 '\n'
143 ' % tools/mb/mb.py run out/Default content_browsertests\n'
144 '\n'
145 ' % tools/mb/mb.py run out/Default content_browsertests -- \\\n'
146 ' --test-launcher-retry-limit=0'
147 '\n'
148 )
149
131 AddCommonOptions(subp) 150 AddCommonOptions(subp)
132 subp.add_argument('-j', '--jobs', dest='jobs', type=int, 151 subp.add_argument('-j', '--jobs', dest='jobs', type=int,
133 help='Number of jobs to pass to ninja') 152 help='Number of jobs to pass to ninja')
134 subp.add_argument('--no-build', dest='build', default=True, 153 subp.add_argument('--no-build', dest='build', default=True,
135 action='store_false', 154 action='store_false',
136 help='Do not build, just isolate and run') 155 help='Do not build, just isolate and run')
137 subp.add_argument('path', nargs=1, 156 subp.add_argument('path', nargs=1,
138 help='path to generate build into') 157 help=('path to generate build into (or use).'
158 ' This can be either a regular path or a '
159 'GN-style source-relative path like '
160 '//out/Default.'))
139 subp.add_argument('target', nargs=1, 161 subp.add_argument('target', nargs=1,
140 help='ninja target to build and run') 162 help='ninja target to build and run')
163 subp.add_argument('extra_args', nargs='*',
164 help=('extra args to pass to the isolate to run. Use '
165 '"--" as the first arg if you need to pass '
166 'switches'))
141 subp.set_defaults(func=self.CmdRun) 167 subp.set_defaults(func=self.CmdRun)
142 168
143 subp = subps.add_parser('validate', 169 subp = subps.add_parser('validate',
144 help='validate the config file') 170 help='validate the config file')
145 subp.add_argument('-f', '--config-file', metavar='PATH', 171 subp.add_argument('-f', '--config-file', metavar='PATH',
146 default=self.default_config, 172 default=self.default_config,
147 help='path to config file ' 173 help='path to config file '
148 '(default is //tools/mb/mb_config.pyl)') 174 '(default is //tools/mb/mb_config.pyl)')
149 subp.set_defaults(func=self.CmdValidate) 175 subp.set_defaults(func=self.CmdValidate)
150 176
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 if ret: 272 if ret:
247 return ret 273 return ret
248 ret = self.RunGNIsolate(vals) 274 ret = self.RunGNIsolate(vals)
249 if ret: 275 if ret:
250 return ret 276 return ret
251 else: 277 else:
252 ret = self.Build('%s_run' % target) 278 ret = self.Build('%s_run' % target)
253 if ret: 279 if ret:
254 return ret 280 return ret
255 281
256 ret, _, _ = self.Run([ 282 cmd = [
257 self.executable, 283 self.executable,
258 self.PathJoin('tools', 'swarming_client', 'isolate.py'), 284 self.PathJoin('tools', 'swarming_client', 'isolate.py'),
259 'run', 285 'run',
260 '-s', 286 '-s',
261 self.ToSrcRelPath('%s/%s.isolated' % (build_dir, target))], 287 self.ToSrcRelPath('%s/%s.isolated' % (build_dir, target)),
262 force_verbose=False, buffer_output=False) 288 ]
289 if self.args.extra_args:
290 cmd += ['--'] + self.args.extra_args
291
292 ret, _, _ = self.Run(cmd, force_verbose=False, buffer_output=False)
263 293
264 return ret 294 return ret
265 295
266 def CmdValidate(self, print_ok=True): 296 def CmdValidate(self, print_ok=True):
267 errs = [] 297 errs = []
268 298
269 # Read the file to make sure it parses. 299 # Read the file to make sure it parses.
270 self.ReadConfigFile() 300 self.ReadConfigFile()
271 301
272 # Build a list of all of the configs referenced by builders. 302 # Build a list of all of the configs referenced by builders.
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 779
750 build_dir = self.args.path[0] 780 build_dir = self.args.path[0]
751 target = self.args.target[0] 781 target = self.args.target[0]
752 target_name = self.GNTargetName(target) 782 target_name = self.GNTargetName(target)
753 command, extra_files = self.GetIsolateCommand(target, vals, gn_isolate_map) 783 command, extra_files = self.GetIsolateCommand(target, vals, gn_isolate_map)
754 784
755 label = gn_isolate_map[target_name]['label'] 785 label = gn_isolate_map[target_name]['label']
756 cmd = self.GNCmd('desc', build_dir, extra_args=[label, 'runtime_deps']) 786 cmd = self.GNCmd('desc', build_dir, extra_args=[label, 'runtime_deps'])
757 ret, out, _ = self.Call(cmd) 787 ret, out, _ = self.Call(cmd)
758 if ret: 788 if ret:
789 if out:
790 self.Print(out)
759 return ret 791 return ret
760 792
761 runtime_deps = out.splitlines() 793 runtime_deps = out.splitlines()
762 794
763 self.WriteIsolateFiles(build_dir, command, target, runtime_deps, 795 self.WriteIsolateFiles(build_dir, command, target, runtime_deps,
764 extra_files) 796 extra_files)
765 797
766 ret, _, _ = self.Run([ 798 ret, _, _ = self.Run([
767 self.executable, 799 self.executable,
768 self.PathJoin('tools', 'swarming_client', 'isolate.py'), 800 self.PathJoin('tools', 'swarming_client', 'isolate.py'),
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 972
941 return cmdline, extra_files 973 return cmdline, extra_files
942 974
943 def ToAbsPath(self, build_path, *comps): 975 def ToAbsPath(self, build_path, *comps):
944 return self.PathJoin(self.chromium_src_dir, 976 return self.PathJoin(self.chromium_src_dir,
945 self.ToSrcRelPath(build_path), 977 self.ToSrcRelPath(build_path),
946 *comps) 978 *comps)
947 979
948 def ToSrcRelPath(self, path): 980 def ToSrcRelPath(self, path):
949 """Returns a relative path from the top of the repo.""" 981 """Returns a relative path from the top of the repo."""
950 # TODO: Support normal paths in addition to source-absolute paths. 982 if path.startswith('//'):
951 assert(path.startswith('//')) 983 return path[2:].replace('/', self.sep)
952 return path[2:].replace('/', self.sep) 984 return self.RelPath(path, self.chromium_src_dir)
953 985
954 def ParseGYPConfigPath(self, path): 986 def ParseGYPConfigPath(self, path):
955 rpath = self.ToSrcRelPath(path) 987 rpath = self.ToSrcRelPath(path)
956 output_dir, _, _ = rpath.rpartition(self.sep) 988 output_dir, _, _ = rpath.rpartition(self.sep)
957 return output_dir 989 return output_dir
958 990
959 def GYPCmd(self, output_dir, vals): 991 def GYPCmd(self, output_dir, vals):
960 gyp_defines = vals['gyp_defines'] 992 gyp_defines = vals['gyp_defines']
961 goma_dir = self.args.goma_dir 993 goma_dir = self.args.goma_dir
962 994
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1144 print_env('GYP_CROSSCOMPILE') 1176 print_env('GYP_CROSSCOMPILE')
1145 print_env('GYP_DEFINES') 1177 print_env('GYP_DEFINES')
1146 1178
1147 if cmd[0] == self.executable: 1179 if cmd[0] == self.executable:
1148 cmd = ['python'] + cmd[1:] 1180 cmd = ['python'] + cmd[1:]
1149 self.Print(*[shell_quoter(arg) for arg in cmd]) 1181 self.Print(*[shell_quoter(arg) for arg in cmd])
1150 1182
1151 def PrintJSON(self, obj): 1183 def PrintJSON(self, obj):
1152 self.Print(json.dumps(obj, indent=2, sort_keys=True)) 1184 self.Print(json.dumps(obj, indent=2, sort_keys=True))
1153 1185
1154 def Print(self, *args, **kwargs): 1186 def GNTargetName(self, target):
1155 # This function largely exists so it can be overridden for testing. 1187 return target[:-len('_apk')] if target.endswith('_apk') else target
1156 print(*args, **kwargs)
1157 1188
1158 def Build(self, target): 1189 def Build(self, target):
1159 build_dir = self.ToSrcRelPath(self.args.path[0]) 1190 build_dir = self.ToSrcRelPath(self.args.path[0])
1160 ninja_cmd = ['ninja', '-C', build_dir] 1191 ninja_cmd = ['ninja', '-C', build_dir]
1161 if self.args.jobs: 1192 if self.args.jobs:
1162 ninja_cmd.extend(['-j', '%d' % self.args.jobs]) 1193 ninja_cmd.extend(['-j', '%d' % self.args.jobs])
1163 ninja_cmd.append(target) 1194 ninja_cmd.append(target)
1164 ret, _, _ = self.Run(ninja_cmd, force_verbose=False, buffer_output=False) 1195 ret, _, _ = self.Run(ninja_cmd, force_verbose=False, buffer_output=False)
1165 return ret 1196 return ret
1166 1197
(...skipping 29 matching lines...) Expand all
1196 1227
1197 def ExpandUser(self, path): 1228 def ExpandUser(self, path):
1198 # This function largely exists so it can be overridden for testing. 1229 # This function largely exists so it can be overridden for testing.
1199 return os.path.expanduser(path) 1230 return os.path.expanduser(path)
1200 1231
1201 def Exists(self, path): 1232 def Exists(self, path):
1202 # This function largely exists so it can be overridden for testing. 1233 # This function largely exists so it can be overridden for testing.
1203 return os.path.exists(path) 1234 return os.path.exists(path)
1204 1235
1205 def Fetch(self, url): 1236 def Fetch(self, url):
1206 1237 # This function largely exists so it can be overridden for testing.
1207 f = urllib2.urlopen(url) 1238 f = urllib2.urlopen(url)
1208 contents = f.read() 1239 contents = f.read()
1209 f.close() 1240 f.close()
1210 return contents 1241 return contents
1211 1242
1212 def GNTargetName(self, target):
1213 return target[:-len('_apk')] if target.endswith('_apk') else target
1214
1215 def MaybeMakeDirectory(self, path): 1243 def MaybeMakeDirectory(self, path):
1216 try: 1244 try:
1217 os.makedirs(path) 1245 os.makedirs(path)
1218 except OSError, e: 1246 except OSError, e:
1219 if e.errno != errno.EEXIST: 1247 if e.errno != errno.EEXIST:
1220 raise 1248 raise
1221 1249
1222 def PathJoin(self, *comps): 1250 def PathJoin(self, *comps):
1223 # This function largely exists so it can be overriden for testing. 1251 # This function largely exists so it can be overriden for testing.
1224 return os.path.join(*comps) 1252 return os.path.join(*comps)
1225 1253
1254 def Print(self, *args, **kwargs):
1255 # This function largely exists so it can be overridden for testing.
1256 print(*args, **kwargs)
1257
1226 def ReadFile(self, path): 1258 def ReadFile(self, path):
1227 # This function largely exists so it can be overriden for testing. 1259 # This function largely exists so it can be overriden for testing.
1228 with open(path) as fp: 1260 with open(path) as fp:
1229 return fp.read() 1261 return fp.read()
1230 1262
1263 def RelPath(self, path, start='.'):
1264 # This function largely exists so it can be overriden for testing.
1265 return os.path.relpath(path, start)
1266
1231 def RemoveFile(self, path): 1267 def RemoveFile(self, path):
1232 # This function largely exists so it can be overriden for testing. 1268 # This function largely exists so it can be overriden for testing.
1233 os.remove(path) 1269 os.remove(path)
1234 1270
1235 def RemoveDirectory(self, abs_path): 1271 def RemoveDirectory(self, abs_path):
1236 if self.platform == 'win32': 1272 if self.platform == 'win32':
1237 # In other places in chromium, we often have to retry this command 1273 # In other places in chromium, we often have to retry this command
1238 # because we're worried about other processes still holding on to 1274 # because we're worried about other processes still holding on to
1239 # file handles, but when MB is invoked, it will be early enough in the 1275 # file handles, but when MB is invoked, it will be early enough in the
1240 # build that their should be no other processes to interfere. We 1276 # build that their should be no other processes to interfere. We
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1283 # Then check to see if the arg contains any metacharacters other than 1319 # Then check to see if the arg contains any metacharacters other than
1284 # double quotes; if it does, quote everything (including the double 1320 # double quotes; if it does, quote everything (including the double
1285 # quotes) for safety. 1321 # quotes) for safety.
1286 if any(a in UNSAFE_FOR_CMD for a in arg): 1322 if any(a in UNSAFE_FOR_CMD for a in arg):
1287 arg = ''.join('^' + a if a in ALL_META_CHARS else a for a in arg) 1323 arg = ''.join('^' + a if a in ALL_META_CHARS else a for a in arg)
1288 return arg 1324 return arg
1289 1325
1290 1326
1291 if __name__ == '__main__': 1327 if __name__ == '__main__':
1292 sys.exit(main(sys.argv[1:])) 1328 sys.exit(main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « testing/buildbot/gn_isolate_map.pyl ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698