blob: fdc46682223fed735454c3bb585bc8e0550b2f5d [file] [log] [blame]
Nathaniel Manistacbf21da2016-02-02 22:17:44 +00001#!/usr/bin/env python2.7
Jan Tattermuschbe538a12016-01-28 14:58:15 -08002# Copyright 2016, Google Inc.
3# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions are
7# met:
8#
9# * Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# * Redistributions in binary form must reproduce the above
12# copyright notice, this list of conditions and the following disclaimer
13# in the documentation and/or other materials provided with the
14# distribution.
15# * Neither the name of Google Inc. nor the names of its
16# contributors may be used to endorse or promote products derived from
17# this software without specific prior written permission.
18#
19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31"""Runs selected gRPC test/build tasks."""
32
siddharthshukla0589e532016-07-07 16:08:01 +020033from __future__ import print_function
34
Jan Tattermuschbe538a12016-01-28 14:58:15 -080035import argparse
Jan Tattermuschbe538a12016-01-28 14:58:15 -080036import multiprocessing
37import sys
38
Jan Tattermusch5c79a312016-12-20 11:02:50 +010039import artifacts.artifact_targets as artifact_targets
40import artifacts.distribtest_targets as distribtest_targets
41import artifacts.package_targets as package_targets
42import python_utils.jobset as jobset
Jan Tattermuschbe538a12016-01-28 14:58:15 -080043
44_TARGETS = []
45_TARGETS += artifact_targets.targets()
Jan Tattermusch38b519a2016-01-27 18:32:42 -080046_TARGETS += distribtest_targets.targets()
Jan Tattermuschbe538a12016-01-28 14:58:15 -080047_TARGETS += package_targets.targets()
48
49def _create_build_map():
50 """Maps task names and labels to list of tasks to be built."""
51 target_build_map = dict([(target.name, [target])
52 for target in _TARGETS])
53 if len(_TARGETS) > len(target_build_map.keys()):
54 raise Exception('Target names need to be unique')
55
56 label_build_map = {}
57 label_build_map['all'] = [t for t in _TARGETS] # to build all targets
58 for target in _TARGETS:
59 for label in target.labels:
60 if label in label_build_map:
61 label_build_map[label].append(target)
62 else:
63 label_build_map[label] = [target]
64
65 if set(target_build_map.keys()).intersection(label_build_map.keys()):
66 raise Exception('Target names need to be distinct from label names')
67 return dict( target_build_map.items() + label_build_map.items())
68
69
70_BUILD_MAP = _create_build_map()
71
72argp = argparse.ArgumentParser(description='Runs build/test targets.')
73argp.add_argument('-b', '--build',
74 choices=sorted(_BUILD_MAP.keys()),
75 nargs='+',
76 default=['all'],
77 help='Target name or target label to build.')
78argp.add_argument('-f', '--filter',
79 choices=sorted(_BUILD_MAP.keys()),
80 nargs='+',
81 default=[],
82 help='Filter targets to build with AND semantics.')
83argp.add_argument('-j', '--jobs', default=multiprocessing.cpu_count(), type=int)
84argp.add_argument('-t', '--travis',
85 default=False,
86 action='store_const',
87 const=True)
88
89args = argp.parse_args()
90
91# Figure out which targets to build
92targets = []
93for label in args.build:
94 targets += _BUILD_MAP[label]
95
96# Among targets selected by -b, filter out those that don't match the filter
97targets = [t for t in targets if all(f in t.labels for f in args.filter)]
98targets = sorted(set(targets))
99
100# Execute pre-build phase
101prebuild_jobs = []
102for target in targets:
103 prebuild_jobs += target.pre_build_jobspecs()
104if prebuild_jobs:
105 num_failures, _ = jobset.run(
106 prebuild_jobs, newline_on_success=True, maxjobs=args.jobs)
107 if num_failures != 0:
108 jobset.message('FAILED', 'Pre-build phase failed.', do_newline=True)
109 sys.exit(1)
110
111build_jobs = []
112for target in targets:
113 build_jobs.append(target.build_jobspec())
114if not build_jobs:
siddharthshukla0589e532016-07-07 16:08:01 +0200115 print('Nothing to build.')
Jan Tattermuschbe538a12016-01-28 14:58:15 -0800116 sys.exit(1)
117
118jobset.message('START', 'Building targets.', do_newline=True)
119num_failures, _ = jobset.run(
120 build_jobs, newline_on_success=True, maxjobs=args.jobs)
121if num_failures == 0:
122 jobset.message('SUCCESS', 'All targets built successfully.',
123 do_newline=True)
124else:
125 jobset.message('FAILED', 'Failed to build targets.',
126 do_newline=True)
127 sys.exit(1)