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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « scripts/tools/buildbot-tool ('k') | scripts/tools/buildbot_tool_templates/Makefile » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 ast
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 # This adjusts sys.path, so must be done before we import other modules.
20 if not SCRIPTS_DIR in sys.path:
21 sys.path.append(SCRIPTS_DIR)
22
23 from common import filesystem
24
25
26 TEMPLATE_SUBPATH = os.path.join('scripts', 'tools', 'buildbot_tool_templates')
27 TEMPLATE_DIR = os.path.join(BASE_DIR, TEMPLATE_SUBPATH)
28
29 BUILDER_TEMPLATE = """\
30 c['builders'].append({
31 'name': '%(builder_name)s',
32 'factory': m_annotator.BaseFactory('%(recipe)s'),
33 'slavebuilddir': '%(slavebuilddir)s'})
34 """
35
36
37 SLAVE_TEMPLATE = """\
38 {
39 'master': '%(master_classname)s',
40 'hostname': '%(hostname)s',
41 'builder': '%(builder_name)s',
42 'os': '%(os)s',
43 'version': '%(version)s',
44 'bits': '%(bits)s',
45 },
46 """
47
48
49 def main(argv, fs):
50 args = parse_args(argv)
51 return args.func(args, fs)
52
53
54 def parse_args(argv):
55 parser = argparse.ArgumentParser()
56 subps = parser.add_subparsers()
57
58 subp = subps.add_parser('gen', help=run_gen.__doc__)
59 subp.add_argument('master_dirname', nargs=1,
60 help='Path to master config directory (must contain '
61 'a builders.py file).')
62 subp.set_defaults(func=run_gen)
63
64 subp = subps.add_parser('help', help=run_help.__doc__)
65 subp.add_argument(nargs='?', action='store', dest='subcommand',
66 help='The command to get help for.')
67 subp.set_defaults(func=run_help)
68
69 return parser.parse_args(argv)
70
71
72 def run_gen(args, fs):
73 """Generate a new master config."""
74
75 master_dirname = args.master_dirname[0]
76 master_subpath = fs.relpath(master_dirname, BASE_DIR)
77 builders_path = fs.join(BASE_DIR, master_subpath, 'builders.py')
78
79 if not fs.exists(builders_path):
80 print("%s not found" % master_dirname, file=sys.stderr)
81 return 1
82
83 values = _values_from_file(fs, builders_path)
84
85 for filename in fs.listfiles(TEMPLATE_DIR):
86 template = fs.read_text_file(fs.join(TEMPLATE_DIR, filename))
87 contents = _expand(template, values,
88 '%s/%s' % (TEMPLATE_SUBPATH, filename),
89 master_subpath)
90 fs.write_text_file(fs.join(BASE_DIR, master_subpath, filename), contents)
91 print("Wrote %s." % filename)
92
93 return 0
94
95
96 def run_help(args, fs):
97 """Get help on a subcommand."""
98
99 if args.subcommand:
100 return main([args.subcommand, '--help'], fs)
101 return main(['--help'], fs)
102
103
104 def _values_from_file(fs, builders_path):
105 builders = ast.literal_eval(fs.read_text_file(builders_path))
106 master_dirname = fs.basename(fs.dirname(builders_path))
107 master_name_comps = master_dirname.split('.')[1:]
108 master_classname = ''.join(c[0].upper() + c[1:] for c in master_name_comps)
109
110 builders_block = ""
111 slaves_block = "slaves = [\n"
112
113 for builder_name, builder_vals in builders['builders'].items():
114 builders_block += BUILDER_TEMPLATE % {
115 'builder_name': builder_name,
116 'recipe': builder_vals['recipe'],
117 'slavebuilddir': builder_vals['slavebuilddir']
118 }
119
120 for pool_name in builder_vals['slave_pools']:
121 pool = builders['slave_pools'][pool_name]
122 slave_data = pool['slave_data']
123 slaves = pool['slaves']
124 for slave in slaves:
125 slaves_block += SLAVE_TEMPLATE % {
126 'master_classname': master_classname,
127 'hostname': slave,
128 'builder_name': builder_name,
129 'os': slave_data['os'],
130 'version': slave_data['version'],
131 'bits': slave_data['bits'],
132 }
133
134 slaves_block += "]"
135
136 v = {}
137 v['builders_block'] = builders_block
138 v['git_repo_url'] = builders['git_repo_url']
139 v['master_dirname'] = master_dirname
140 v['master_classname'] = master_classname
141 v['master_base_class'] = builders['master_base_class']
142 v['master_port'] = builders['master_port']
143 v['master_port_alt'] = builders['master_port_alt']
144 v['slave_port'] = builders['slave_port']
145 v['slaves_block'] = slaves_block
146 return v
147
148
149 def _expand(template, values, source, master_subpath):
150 try:
151 contents = template % values
152 except:
153 print("Error populating template %s" % source, file=sys.stderr)
154 raise
155 return _update_generated_file_disclaimer(contents, source, master_subpath)
156
157
158 def _update_generated_file_disclaimer(contents, source, master_subpath):
159 pattern = '# This file is used by scripts/tools/buildbot-tool.*'
160 replacement = ('# This file was generated from\n'
161 '# %s\n'
162 '# by "scripts/tools/buildbot-tool gen %s".\n'
163 '# DO NOT EDIT BY HAND!\n' %
164 (source, master_subpath))
165 return re.sub(pattern, replacement, contents)
166
167
168 if __name__ == '__main__': # pragma: no cover
169 sys.exit(main(sys.argv[1:], filesystem.Filesystem()))
OLDNEW
« 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