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

Unified Diff: scripts/tools/buildbot_tool.py

Issue 761253003: Add a new buildbot-tool generator for master configs (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: merge to head Created 6 years 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « scripts/tools/buildbot-tool ('k') | scripts/tools/buildbot_tool_templates/Makefile » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: scripts/tools/buildbot_tool.py
diff --git a/scripts/tools/buildbot_tool.py b/scripts/tools/buildbot_tool.py
new file mode 100755
index 0000000000000000000000000000000000000000..7f5aa54aab365de89886640ed0e5055b2f10a40e
--- /dev/null
+++ b/scripts/tools/buildbot_tool.py
@@ -0,0 +1,169 @@
+#!/usr/bin/python
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+from __future__ import print_function
+
+import argparse
+import ast
+import os
+import re
+import sys
+
+
+TOOLS_DIR = os.path.abspath(os.path.dirname(__file__))
+SCRIPTS_DIR = os.path.dirname(TOOLS_DIR)
+BASE_DIR = os.path.dirname(SCRIPTS_DIR)
+
+# This adjusts sys.path, so must be done before we import other modules.
+if not SCRIPTS_DIR in sys.path:
+ sys.path.append(SCRIPTS_DIR)
+
+from common import filesystem
+
+
+TEMPLATE_SUBPATH = os.path.join('scripts', 'tools', 'buildbot_tool_templates')
+TEMPLATE_DIR = os.path.join(BASE_DIR, TEMPLATE_SUBPATH)
+
+BUILDER_TEMPLATE = """\
+c['builders'].append({
+ 'name': '%(builder_name)s',
+ 'factory': m_annotator.BaseFactory('%(recipe)s'),
+ 'slavebuilddir': '%(slavebuilddir)s'})
+"""
+
+
+SLAVE_TEMPLATE = """\
+ {
+ 'master': '%(master_classname)s',
+ 'hostname': '%(hostname)s',
+ 'builder': '%(builder_name)s',
+ 'os': '%(os)s',
+ 'version': '%(version)s',
+ 'bits': '%(bits)s',
+ },
+"""
+
+
+def main(argv, fs):
+ args = parse_args(argv)
+ return args.func(args, fs)
+
+
+def parse_args(argv):
+ parser = argparse.ArgumentParser()
+ subps = parser.add_subparsers()
+
+ subp = subps.add_parser('gen', help=run_gen.__doc__)
+ subp.add_argument('master_dirname', nargs=1,
+ help='Path to master config directory (must contain '
+ 'a builders.py file).')
+ subp.set_defaults(func=run_gen)
+
+ subp = subps.add_parser('help', help=run_help.__doc__)
+ subp.add_argument(nargs='?', action='store', dest='subcommand',
+ help='The command to get help for.')
+ subp.set_defaults(func=run_help)
+
+ return parser.parse_args(argv)
+
+
+def run_gen(args, fs):
+ """Generate a new master config."""
+
+ master_dirname = args.master_dirname[0]
+ master_subpath = fs.relpath(master_dirname, BASE_DIR)
+ builders_path = fs.join(BASE_DIR, master_subpath, 'builders.py')
+
+ if not fs.exists(builders_path):
+ print("%s not found" % master_dirname, file=sys.stderr)
+ return 1
+
+ values = _values_from_file(fs, builders_path)
+
+ for filename in fs.listfiles(TEMPLATE_DIR):
+ template = fs.read_text_file(fs.join(TEMPLATE_DIR, filename))
+ contents = _expand(template, values,
+ '%s/%s' % (TEMPLATE_SUBPATH, filename),
+ master_subpath)
+ fs.write_text_file(fs.join(BASE_DIR, master_subpath, filename), contents)
+ print("Wrote %s." % filename)
+
+ return 0
+
+
+def run_help(args, fs):
+ """Get help on a subcommand."""
+
+ if args.subcommand:
+ return main([args.subcommand, '--help'], fs)
+ return main(['--help'], fs)
+
+
+def _values_from_file(fs, builders_path):
+ builders = ast.literal_eval(fs.read_text_file(builders_path))
+ master_dirname = fs.basename(fs.dirname(builders_path))
+ master_name_comps = master_dirname.split('.')[1:]
+ master_classname = ''.join(c[0].upper() + c[1:] for c in master_name_comps)
+
+ builders_block = ""
+ slaves_block = "slaves = [\n"
+
+ for builder_name, builder_vals in builders['builders'].items():
+ builders_block += BUILDER_TEMPLATE % {
+ 'builder_name': builder_name,
+ 'recipe': builder_vals['recipe'],
+ 'slavebuilddir': builder_vals['slavebuilddir']
+ }
+
+ for pool_name in builder_vals['slave_pools']:
+ pool = builders['slave_pools'][pool_name]
+ slave_data = pool['slave_data']
+ slaves = pool['slaves']
+ for slave in slaves:
+ slaves_block += SLAVE_TEMPLATE % {
+ 'master_classname': master_classname,
+ 'hostname': slave,
+ 'builder_name': builder_name,
+ 'os': slave_data['os'],
+ 'version': slave_data['version'],
+ 'bits': slave_data['bits'],
+ }
+
+ slaves_block += "]"
+
+ v = {}
+ v['builders_block'] = builders_block
+ v['git_repo_url'] = builders['git_repo_url']
+ v['master_dirname'] = master_dirname
+ v['master_classname'] = master_classname
+ v['master_base_class'] = builders['master_base_class']
+ v['master_port'] = builders['master_port']
+ v['master_port_alt'] = builders['master_port_alt']
+ v['slave_port'] = builders['slave_port']
+ v['slaves_block'] = slaves_block
+ return v
+
+
+def _expand(template, values, source, master_subpath):
+ try:
+ contents = template % values
+ except:
+ print("Error populating template %s" % source, file=sys.stderr)
+ raise
+ return _update_generated_file_disclaimer(contents, source, master_subpath)
+
+
+def _update_generated_file_disclaimer(contents, source, master_subpath):
+ pattern = '# This file is used by scripts/tools/buildbot-tool.*'
+ replacement = ('# This file was generated from\n'
+ '# %s\n'
+ '# by "scripts/tools/buildbot-tool gen %s".\n'
+ '# DO NOT EDIT BY HAND!\n' %
+ (source, master_subpath))
+ return re.sub(pattern, replacement, contents)
+
+
+if __name__ == '__main__': # pragma: no cover
+ sys.exit(main(sys.argv[1:], filesystem.Filesystem()))
« no previous file with comments | « scripts/tools/buildbot-tool ('k') | scripts/tools/buildbot_tool_templates/Makefile » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698