blob: f985007145cbed4a889c5a1afe56f340d29d49cc [file] [log] [blame]
stip@chromium.orga3d7c4b2013-11-20 02:14:08 +00001#!/usr/bin/env python
2# Copyright 2013 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"""Wraps gclient calls with annotated output.
7
8Note that you will have to use -- to stop option parsing for gclient flags.
9
10To run `gclient sync --gclientfile=.gclient` and annotate got_v8_revision:
11 `annotated_gclient.py --revision-mapping='{"src/v8": "got_v8_revision"}' --
12 sync --gclientfile=.gclient`
13"""
14
Raul Tambre80ee78e2019-05-06 22:41:05 +000015from __future__ import print_function
16
stip@chromium.orga3d7c4b2013-11-20 02:14:08 +000017import contextlib
18import json
19import optparse
20import os
21import subprocess
22import sys
23import tempfile
24
25
26@contextlib.contextmanager
27def temp_filename(suffix='', prefix='tmp'):
28 output_fd, output_file = tempfile.mkstemp(suffix=suffix, prefix=prefix)
29 os.close(output_fd)
30
31 yield output_file
32
33 try:
34 os.remove(output_file)
35 except OSError as e:
Raul Tambre80ee78e2019-05-06 22:41:05 +000036 print('Error cleaning up temp file %s: %s' % (output_file, e))
stip@chromium.orga3d7c4b2013-11-20 02:14:08 +000037
38
39def parse_got_revision(filename, revision_mapping):
40 result = {}
41 with open(filename) as f:
42 data = json.load(f)
43
44 for path, info in data['solutions'].iteritems():
45 # gclient json paths always end with a slash
46 path = path.rstrip('/')
47 if path in revision_mapping:
48 propname = revision_mapping[path]
49 result[propname] = info['revision']
50
51 return result
52
53
54def emit_buildprops(got_revisions):
55 for prop, revision in got_revisions.iteritems():
Raul Tambre80ee78e2019-05-06 22:41:05 +000056 print('@@@SET_BUILD_PROPERTY@%s@%s@@@' % (prop, json.dumps(revision)))
stip@chromium.orga3d7c4b2013-11-20 02:14:08 +000057
58
59def main():
60 parser = optparse.OptionParser(
61 description=('Runs gclient and annotates the output with any '
62 'got_revisions.'))
63 parser.add_option('--revision-mapping', default='{}',
64 help='json dict of directory-to-property mappings.')
65 parser.add_option('--suffix', default='gclient',
66 help='tempfile suffix')
67 opts, args = parser.parse_args()
68
69 revision_mapping = json.loads(opts.revision_mapping)
70
71 if not args:
72 parser.error('Must provide arguments to gclient.')
73
74 if any(a.startswith('--output-json') for a in args):
75 parser.error('Can\'t call annotated_gclient with --output-json.')
76
77 with temp_filename(opts.suffix) as f:
78 cmd = ['gclient']
79 cmd.extend(args)
80 cmd.extend(['--output-json', f])
81 p = subprocess.Popen(cmd)
82 p.wait()
83
84 if p.returncode == 0:
85 revisions = parse_got_revision(f, revision_mapping)
86 emit_buildprops(revisions)
87 return p.returncode
88
89
90if __name__ == '__main__':
91 sys.exit(main())