yapf tools/buildgen

pull/13719/head
ncteisen 7 years ago
parent 7fd341746b
commit 26d70b1653
  1. 26
      tools/buildgen/build-cleaner.py
  2. 5
      tools/buildgen/bunch.py
  3. 7
      tools/buildgen/generate_projects.py
  4. 18
      tools/buildgen/mako_renderer.py
  5. 1
      tools/buildgen/plugins/expand_bin_attrs.py
  6. 10
      tools/buildgen/plugins/expand_filegroups.py
  7. 15
      tools/buildgen/plugins/expand_version.py
  8. 24
      tools/buildgen/plugins/generate_vsprojects.py
  9. 9
      tools/buildgen/plugins/list_api.py
  10. 2
      tools/buildgen/plugins/list_protos.py
  11. 8
      tools/buildgen/plugins/make_fuzzer_tests.py
  12. 12
      tools/buildgen/plugins/transitive_dependencies.py
  13. 1
      tools/distrib/yapf_code.sh

@ -22,25 +22,22 @@ import yaml
TEST = (os.environ.get('TEST', 'false') == 'true') TEST = (os.environ.get('TEST', 'false') == 'true')
_TOP_LEVEL_KEYS = ['settings', 'proto_deps', 'filegroups', 'libs', 'targets', 'vspackages'] _TOP_LEVEL_KEYS = [
'settings', 'proto_deps', 'filegroups', 'libs', 'targets', 'vspackages'
]
_ELEM_KEYS = [ _ELEM_KEYS = [
'name', 'name', 'gtest', 'cpu_cost', 'flaky', 'build', 'run', 'language',
'gtest', 'public_headers', 'headers', 'src', 'deps'
'cpu_cost', ]
'flaky',
'build',
'run',
'language',
'public_headers',
'headers',
'src',
'deps']
def repr_ordered_dict(dumper, odict): def repr_ordered_dict(dumper, odict):
return dumper.represent_mapping(u'tag:yaml.org,2002:map', odict.items()) return dumper.represent_mapping(u'tag:yaml.org,2002:map', odict.items())
yaml.add_representer(collections.OrderedDict, repr_ordered_dict) yaml.add_representer(collections.OrderedDict, repr_ordered_dict)
def rebuild_as_ordered_dict(indict, special_keys): def rebuild_as_ordered_dict(indict, special_keys):
outdict = collections.OrderedDict() outdict = collections.OrderedDict()
for key in sorted(indict.keys()): for key in sorted(indict.keys()):
@ -55,6 +52,7 @@ def rebuild_as_ordered_dict(indict, special_keys):
outdict[key] = indict[key] outdict[key] = indict[key]
return outdict return outdict
def clean_elem(indict): def clean_elem(indict):
for name in ['public_headers', 'headers', 'src']: for name in ['public_headers', 'headers', 'src']:
if name not in indict: continue if name not in indict: continue
@ -64,13 +62,15 @@ def clean_elem(indict):
indict[name] = protos + sorted(others) indict[name] = protos + sorted(others)
return rebuild_as_ordered_dict(indict, _ELEM_KEYS) return rebuild_as_ordered_dict(indict, _ELEM_KEYS)
for filename in sys.argv[1:]: for filename in sys.argv[1:]:
with open(filename) as f: with open(filename) as f:
js = yaml.load(f) js = yaml.load(f)
js = rebuild_as_ordered_dict(js, _TOP_LEVEL_KEYS) js = rebuild_as_ordered_dict(js, _TOP_LEVEL_KEYS)
for grp in ['filegroups', 'libs', 'targets']: for grp in ['filegroups', 'libs', 'targets']:
if grp not in js: continue if grp not in js: continue
js[grp] = sorted([clean_elem(x) for x in js[grp]], js[grp] = sorted(
[clean_elem(x) for x in js[grp]],
key=lambda x: (x.get('language', '_'), x['name'])) key=lambda x: (x.get('language', '_'), x['name']))
output = yaml.dump(js, indent=2, width=80, default_flow_style=False) output = yaml.dump(js, indent=2, width=80, default_flow_style=False)
# massage out trailing whitespace # massage out trailing whitespace

@ -11,7 +11,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
"""Allows dot-accessible dictionaries.""" """Allows dot-accessible dictionaries."""
@ -49,5 +48,5 @@ def merge_json(dst, add):
elif isinstance(dst, list) and isinstance(add, list): elif isinstance(dst, list) and isinstance(add, list):
dst.extend(add) dst.extend(add)
else: else:
raise Exception('Tried to merge incompatible objects %s %s\n\n%r\n\n%r' % (type(dst).__name__, type(add).__name__, dst, add)) raise Exception('Tried to merge incompatible objects %s %s\n\n%r\n\n%r'
% (type(dst).__name__, type(add).__name__, dst, add))

@ -21,7 +21,9 @@ import shutil
import sys import sys
import tempfile import tempfile
import multiprocessing import multiprocessing
sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), '..', 'run_tests', 'python_utils')) sys.path.append(
os.path.join(
os.path.dirname(sys.argv[0]), '..', 'run_tests', 'python_utils'))
assert sys.argv[1:], 'run generate_projects.sh instead of this directly' assert sys.argv[1:], 'run generate_projects.sh instead of this directly'
@ -64,7 +66,8 @@ cmd.append(preprocessed_build)
if args.output_merged is not None: if args.output_merged is not None:
cmd.append('-M') cmd.append('-M')
cmd.append(args.output_merged) cmd.append(args.output_merged)
pre_jobs.append(jobset.JobSpec(cmd, shortname='preprocess', timeout_seconds=None)) pre_jobs.append(
jobset.JobSpec(cmd, shortname='preprocess', timeout_seconds=None))
jobs = [] jobs = []
for template in reversed(sorted(templates)): for template in reversed(sorted(templates)):

@ -12,8 +12,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
"""Simple Mako renderer. """Simple Mako renderer.
Just a wrapper around the mako rendering library. Just a wrapper around the mako rendering library.
@ -27,7 +25,6 @@ import cPickle as pickle
import shutil import shutil
import sys import sys
from mako.lookup import TemplateLookup from mako.lookup import TemplateLookup
from mako.runtime import Context from mako.runtime import Context
from mako.template import Template from mako.template import Template
@ -102,7 +99,10 @@ def main(argv):
elif opt == '-P': elif opt == '-P':
assert not got_preprocessed_input assert not got_preprocessed_input
assert json_dict == {} assert json_dict == {}
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), 'plugins'))) sys.path.insert(
0,
os.path.abspath(
os.path.join(os.path.dirname(sys.argv[0]), 'plugins')))
with open(arg, 'r') as dict_file: with open(arg, 'r') as dict_file:
dictionary = pickle.load(dict_file) dictionary = pickle.load(dict_file)
got_preprocessed_input = True got_preprocessed_input = True
@ -136,7 +136,8 @@ def main(argv):
for src in srcs: for src in srcs:
if isinstance(src, basestring): if isinstance(src, basestring):
assert len(srcs) == 1 assert len(srcs) == 1
template = Template(src, template = Template(
src,
filename=arg, filename=arg,
module_directory=module_directory, module_directory=module_directory,
lookup=TemplateLookup(directories=['.'])) lookup=TemplateLookup(directories=['.']))
@ -169,10 +170,12 @@ def main(argv):
args = dict(dictionary) args = dict(dictionary)
args['selected'] = item args['selected'] = item
item_output_name = os.path.join( item_output_name = os.path.join(
output_name, Template(src['output_name']).render(**args)) output_name,
Template(src['output_name']).render(**args))
if not os.path.exists(os.path.dirname(item_output_name)): if not os.path.exists(os.path.dirname(item_output_name)):
os.makedirs(os.path.dirname(item_output_name)) os.makedirs(os.path.dirname(item_output_name))
template = Template(src['template'], template = Template(
src['template'],
filename=arg, filename=arg,
module_directory=module_directory, module_directory=module_directory,
lookup=TemplateLookup(directories=['.'])) lookup=TemplateLookup(directories=['.']))
@ -183,5 +186,6 @@ def main(argv):
out('Got nothing to do') out('Got nothing to do')
showhelp() showhelp()
if __name__ == '__main__': if __name__ == '__main__':
main(sys.argv[1:]) main(sys.argv[1:])

@ -11,7 +11,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
"""Buildgen expand binary attributes plugin. """Buildgen expand binary attributes plugin.
This fills in any optional attributes. This fills in any optional attributes.

@ -11,7 +11,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
"""Buildgen expand filegroups plugin. """Buildgen expand filegroups plugin.
This takes the list of libs from our yaml dictionary, This takes the list of libs from our yaml dictionary,
@ -37,7 +36,6 @@ def uniquify(lst):
FILEGROUP_LISTS = ['src', 'headers', 'public_headers', 'deps'] FILEGROUP_LISTS = ['src', 'headers', 'public_headers', 'deps']
FILEGROUP_DEFAULTS = { FILEGROUP_DEFAULTS = {
'language': 'c', 'language': 'c',
'boringssl': False, 'boringssl': False,
@ -71,7 +69,10 @@ def mako_plugin(dictionary):
skips = 0 skips = 0
while todo: while todo:
assert skips != len(todo), "infinite loop in filegroup uses clauses: %r" % [t['name'] for t in todo] assert skips != len(
todo), "infinite loop in filegroup uses clauses: %r" % [
t['name'] for t in todo
]
# take the first element of the todo list # take the first element of the todo list
cur = todo[0] cur = todo[0]
todo = todo[1:] todo = todo[1:]
@ -103,7 +104,8 @@ def mako_plugin(dictionary):
# build reverse dependency map # build reverse dependency map
things = {} things = {}
for thing in dictionary['libs'] + dictionary['targets'] + dictionary['filegroups']: for thing in dictionary['libs'] + dictionary['targets'] + dictionary[
'filegroups']:
things[thing['name']] = thing things[thing['name']] = thing
thing['used_by'] = [] thing['used_by'] = []
thing_deps = lambda t: t.get('uses', []) + t.get('filegroups', []) + t.get('deps', []) thing_deps = lambda t: t.get('uses', []) + t.get('filegroups', []) + t.get('deps', [])

@ -11,7 +11,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
"""Buildgen package version plugin """Buildgen package version plugin
This parses the list of targets from the yaml build file, and creates This parses the list of targets from the yaml build file, and creates
@ -19,7 +18,6 @@ a custom version string for each language's package.
""" """
import re import re
LANGUAGES = [ LANGUAGES = [
@ -32,6 +30,7 @@ LANGUAGES = [
'ruby', 'ruby',
] ]
class Version: class Version:
def __init__(self, s): def __init__(self, s):
@ -58,13 +57,16 @@ class Version:
elif len(self.tag) >= 3 and self.tag[0:3] == 'pre': elif len(self.tag) >= 3 and self.tag[0:3] == 'pre':
s += 'rc%d' % int(self.tag[3:]) s += 'rc%d' % int(self.tag[3:])
else: else:
raise Exception('Don\'t know how to translate version tag "%s" to pep440' % self.tag) raise Exception(
'Don\'t know how to translate version tag "%s" to pep440' %
self.tag)
return s return s
def ruby(self): def ruby(self):
"""Version string in Ruby style""" """Version string in Ruby style"""
if self.tag: if self.tag:
return '%d.%d.%d.%s' % (self.major, self.minor, self.patch, self.tag) return '%d.%d.%d.%s' % (self.major, self.minor, self.patch,
self.tag)
else: else:
return '%d.%d.%d' % (self.major, self.minor, self.patch) return '%d.%d.%d' % (self.major, self.minor, self.patch)
@ -77,13 +79,16 @@ class Version:
elif len(self.tag) >= 3 and self.tag[0:3] == 'pre': elif len(self.tag) >= 3 and self.tag[0:3] == 'pre':
s += 'RC%d' % int(self.tag[3:]) s += 'RC%d' % int(self.tag[3:])
else: else:
raise Exception('Don\'t know how to translate version tag "%s" to PECL version' % self.tag) raise Exception(
'Don\'t know how to translate version tag "%s" to PECL version'
% self.tag)
return s return s
def php_composer(self): def php_composer(self):
"""Version string for PHP Composer package""" """Version string for PHP Composer package"""
return '%d.%d.%d' % (self.major, self.minor, self.patch) return '%d.%d.%d' % (self.major, self.minor, self.patch)
def mako_plugin(dictionary): def mako_plugin(dictionary):
"""Expand version numbers: """Expand version numbers:
- for each language, ensure there's a language_version tag in - for each language, ensure there's a language_version tag in

@ -11,7 +11,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
"""Buildgen vsprojects plugin. """Buildgen vsprojects plugin.
This parses the list of libraries, and generates globals "vsprojects" This parses the list of libraries, and generates globals "vsprojects"
@ -19,7 +18,6 @@ and "vsproject_dict", to be used by the visual studio generators.
""" """
import hashlib import hashlib
import re import re
@ -57,18 +55,24 @@ def mako_plugin(dictionary):
if 'vs_props' not in target: if 'vs_props' not in target:
target['vs_props'] = [] target['vs_props'] = []
target['vs_proj_dir'] = target.get('vs_proj_dir', default_test_dir) target['vs_proj_dir'] = target.get('vs_proj_dir', default_test_dir)
if target.get('vs_project_guid', None) is None and 'windows' in target.get('platforms', ['windows']): if target.get('vs_project_guid',
None) is None and 'windows' in target.get('platforms',
['windows']):
name = target['name'] name = target['name']
guid = re.sub('(........)(....)(....)(....)(.*)', guid = re.sub('(........)(....)(....)(....)(.*)',
r'{\1-\2-\3-\4-\5}', r'{\1-\2-\3-\4-\5}', hashlib.md5(name).hexdigest())
hashlib.md5(name).hexdigest())
target['vs_project_guid'] = guid.upper() target['vs_project_guid'] = guid.upper()
# Exclude projects without a visual project guid, such as the tests. # Exclude projects without a visual project guid, such as the tests.
projects = [project for project in projects projects = [
if project.get('vs_project_guid', None)] project for project in projects if project.get('vs_project_guid', None)
]
projects = [project for project in projects
if project['language'] != 'c++' or project['build'] == 'all' or project['build'] == 'protoc' or (project['language'] == 'c++' and (project['build'] == 'test' or project['build'] == 'private'))] projects = [
project for project in projects
if project['language'] != 'c++' or project['build'] == 'all' or project[
'build'] == 'protoc' or (project['language'] == 'c++' and (project[
'build'] == 'test' or project['build'] == 'private'))
]
project_dict = dict([(p['name'], p) for p in projects]) project_dict = dict([(p['name'], p) for p in projects])

@ -21,7 +21,6 @@ import re
import sys import sys
import yaml import yaml
_RE_API = r'(?:GPRAPI|GRPCAPI|CENSUSAPI)([^;]*);' _RE_API = r'(?:GPRAPI|GRPCAPI|CENSUSAPI)([^;]*);'
@ -38,7 +37,12 @@ def list_c_apis(filenames):
type_end = max(last_space, last_star) type_end = max(last_space, last_star)
return_type = type_and_name[0:type_end + 1].strip() return_type = type_and_name[0:type_end + 1].strip()
name = type_and_name[type_end + 1:].strip() name = type_and_name[type_end + 1:].strip()
yield {'return_type': return_type, 'name': name, 'arguments': args, 'header': filename} yield {
'return_type': return_type,
'name': name,
'arguments': args,
'header': filename
}
def headers_under(directory): def headers_under(directory):
@ -61,4 +65,3 @@ def mako_plugin(dictionary):
if __name__ == '__main__': if __name__ == '__main__':
print yaml.dump([api for api in list_c_apis(headers_under('include/grpc'))]) print yaml.dump([api for api in list_c_apis(headers_under('include/grpc'))])

@ -11,7 +11,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
"""Buildgen .proto files list plugin. """Buildgen .proto files list plugin.
This parses the list of targets from the yaml build file, and creates This parses the list of targets from the yaml build file, and creates
@ -19,7 +18,6 @@ a list called "protos" that contains all of the proto file names.
""" """
import re import re

@ -11,12 +11,12 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
"""Create tests for each fuzzer""" """Create tests for each fuzzer"""
import copy import copy
import glob import glob
def mako_plugin(dictionary): def mako_plugin(dictionary):
targets = dictionary['targets'] targets = dictionary['targets']
tests = dictionary['tests'] tests = dictionary['tests']
@ -26,8 +26,10 @@ def mako_plugin(dictionary):
new_target['build'] = 'test' new_target['build'] = 'test'
new_target['name'] += '_one_entry' new_target['name'] += '_one_entry'
new_target['run'] = False new_target['run'] = False
new_target['src'].append('test/core/util/one_corpus_entry_fuzzer.cc') new_target['src'].append(
new_target['own_src'].append('test/core/util/one_corpus_entry_fuzzer.cc') 'test/core/util/one_corpus_entry_fuzzer.cc')
new_target['own_src'].append(
'test/core/util/one_corpus_entry_fuzzer.cc')
targets.append(new_target) targets.append(new_target)
for corpus in new_target['corpus_dirs']: for corpus in new_target['corpus_dirs']:
for fn in sorted(glob.glob('%s/*' % corpus)): for fn in sorted(glob.glob('%s/*' % corpus)):

@ -11,7 +11,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
"""Buildgen transitive dependencies """Buildgen transitive dependencies
This takes the list of libs, node_modules, and targets from our This takes the list of libs, node_modules, and targets from our
@ -20,21 +19,26 @@ of the list of dependencies.
""" """
def get_lib(libs, name): def get_lib(libs, name):
try: try:
return next(lib for lib in libs if lib['name'] == name) return next(lib for lib in libs if lib['name'] == name)
except StopIteration: except StopIteration:
return None return None
def transitive_deps(lib, libs): def transitive_deps(lib, libs):
if lib is not None and 'deps' in lib: if lib is not None and 'deps' in lib:
# Recursively call transitive_deps on each dependency, and take the union # Recursively call transitive_deps on each dependency, and take the union
return set.union(set(lib['deps']), return set.union(
*[set(transitive_deps(get_lib(libs, dep), libs)) set(lib['deps']), *[
for dep in lib['deps']]) set(transitive_deps(get_lib(libs, dep), libs))
for dep in lib['deps']
])
else: else:
return set() return set()
def mako_plugin(dictionary): def mako_plugin(dictionary):
"""The exported plugin code for transitive_dependencies. """The exported plugin code for transitive_dependencies.

@ -20,6 +20,7 @@ cd "$(dirname "${0}")/../.."
DIRS=( DIRS=(
'src/python' 'src/python'
'tools/buildgen'
) )
EXCLUSIONS=( EXCLUSIONS=(
'grpcio/grpc_*.py' 'grpcio/grpc_*.py'

Loading…
Cancel
Save