Chromium Code Reviews| OLD | NEW | 
|---|---|
| (Empty) | |
| 1 #!/usr/bin/python | |
| 2 # Copyright 2014 The Chromium Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 from __future__ import print_function | |
| 7 | |
| 8 import argparse | |
| 9 import json | |
| 10 import os | |
| 11 import re | |
| 12 import sys | |
| 13 | |
| 14 | |
| 15 TOOLS_DIR = os.path.abspath(os.path.dirname(__file__)) | |
| 16 SCRIPTS_DIR = os.path.dirname(TOOLS_DIR) | |
| 17 BASE_DIR = os.path.dirname(SCRIPTS_DIR) | |
| 18 | |
| 19 if not SCRIPTS_DIR in sys.path: | |
| 20 sys.path.insert(0, SCRIPTS_DIR) | |
| 21 | |
| 22 from common import filesystem | |
| 23 | |
| 24 | |
| 25 TEMPLATE_SUBPATH = os.path.join('scripts', 'tools', 'buildbot_tool_templates') | |
| 26 TEMPLATE_DIR = os.path.join(BASE_DIR, TEMPLATE_SUBPATH) | |
| 27 | |
| 28 BUILDER_TEMPLATE = """\ | |
| 29 c['builders'].append({ | |
| 30 'name': '%(builder_name)s', | |
| 31 'factory': m_annotator.BaseFactory('%(recipe)s'), | |
| 32 'slavebuilddir': '%(slavebuilddir)s'}) | |
| 33 """ | |
| 34 | |
| 35 | |
| 36 SLAVE_TEMPLATE = """\ | |
| 37 { | |
| 38 'master': '%(master_classname)s', | |
| 39 'hostname': '%(hostname)s', | |
| 40 'builder': '%(builder_name)s', | |
| 41 'os': '%(os)s', | |
| 42 'version': '%(version)s', | |
| 43 'bits': '%(bits)s', | |
| 44 }, | |
| 45 """ | |
| 46 | |
| 47 | |
| 48 def main(argv): | |
| 49 args = parse_args(argv) | |
| 50 return args.func(args, filesystem.Filesystem()) | |
| 51 | |
| 52 | |
| 53 def parse_args(argv): | |
| 54 parser = argparse.ArgumentParser() | |
| 55 subps = parser.add_subparsers() | |
| 56 subp = subps.add_parser("gen", help="generate a new master") | |
| 57 subp.add_argument('builders_json', nargs=1, | |
| 58 help='path to builders.json file') | |
| 
 
agable
2014/12/09 21:13:24
Yeah, path-to-master-directory makes more sense to
 
Dirk Pranke
2014/12/09 21:32:00
Acknowledged.
 
 | |
| 59 subp.set_defaults(func=gen) | |
| 60 return parser.parse_args(argv) | |
| 61 | |
| 62 | |
| 63 def gen(args, fs): | |
| 64 builders_path = fs.abspath(args.builders_json[0]) | |
| 65 | |
| 66 if not fs.exists(builders_path): | |
| 67 print("%s not found" % args.builders_json[0], file=sys.stderr) | |
| 68 return 1 | |
| 69 | |
| 70 values = _values_from_file(fs, builders_path) | |
| 71 | |
| 72 master_dir = fs.dirname(builders_path) | |
| 73 | |
| 74 for filename in fs.listfiles(TEMPLATE_DIR): | |
| 75 template = fs.read_text_file(fs.join(TEMPLATE_DIR, filename)) | |
| 76 contents = _expand(template, values, | |
| 77 '%s/%s' % (TEMPLATE_SUBPATH, filename)) | |
| 78 fs.write_text_file(fs.join(master_dir, filename), contents) | |
| 79 print("Wrote %s." % filename) | |
| 80 | |
| 81 return 0 | |
| 82 | |
| 83 | |
| 84 def _values_from_file(fs, builders_path): | |
| 85 builders = json.loads(fs.read_text_file(builders_path)) | |
| 86 master_dirname = fs.basename(fs.dirname(builders_path)) | |
| 87 master_name_comps = master_dirname.split('.')[1:] | |
| 88 master_classname = ''.join(c[0].upper() + c[1:] for c in master_name_comps) | |
| 89 | |
| 90 builders_block = "" | |
| 91 slaves_block = "slaves = [\n" | |
| 92 | |
| 93 for builder_name, builder_vals in builders['builders'].items(): | |
| 94 builders_block += BUILDER_TEMPLATE % { | |
| 95 'builder_name': builder_name, | |
| 96 'recipe': builder_vals['recipe'], | |
| 97 'slavebuilddir': builder_vals['slavebuilddir'] | |
| 98 } | |
| 99 | |
| 100 for pool_name in builder_vals['slave_pools']: | |
| 101 pool = builders['slave_pools'][pool_name] | |
| 102 slave_data = pool['slave_data'] | |
| 103 slaves = pool['slaves'] | |
| 104 for slave in slaves: | |
| 105 slaves_block += SLAVE_TEMPLATE % { | |
| 106 'master_classname': master_classname, | |
| 107 'hostname': slave, | |
| 108 'builder_name': builder_name, | |
| 109 'os': slave_data['os'], | |
| 110 'version': slave_data['version'], | |
| 111 'bits': slave_data['bits'], | |
| 112 } | |
| 113 | |
| 114 slaves_block += "]" | |
| 115 | |
| 116 v = {} | |
| 117 v['builders_block'] = builders_block | |
| 118 v['git_repo_url'] = builders['git_repo_url'] | |
| 119 v['master_dirname'] = master_dirname | |
| 120 v['master_classname'] = master_classname | |
| 121 v['master_base_class'] = builders['master_base_class'] | |
| 122 v['master_port'] = builders['master_port'] | |
| 123 v['master_port_alt'] = builders['master_port_alt'] | |
| 124 v['slave_port'] = builders['slave_port'] | |
| 125 v['slaves_block'] = slaves_block | |
| 126 return v | |
| 127 | |
| 128 | |
| 129 def _expand(template, values, source): | |
| 130 try: | |
| 131 contents = template % values | |
| 132 except: | |
| 133 print("Error populating template %s" % source, file=sys.stderr) | |
| 134 raise | |
| 135 return _update_generated_file_disclaimer(contents, source) | |
| 136 | |
| 137 | |
| 138 def _update_generated_file_disclaimer(contents, source): | |
| 139 gen_msg = ('# This file was generated from\n' | |
| 140 '# %s\n' | |
| 141 '# by scripts/tools/buildbot-tool.\n' | |
| 142 '# DO NOT EDIT BY HAND!\n' % | |
| 143 source) | |
| 144 return re.sub('# This file is used by scripts/tools/buildbot-tool.*', | |
| 145 gen_msg, contents) | |
| 146 | |
| 147 | |
| 148 if __name__ == '__main__': | |
| 149 sys.exit(main(sys.argv[1:])) | |
| OLD | NEW |