#!/usr/bin/env python # Copyright 2013 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. """Wraps gclient calls with annotated output. Note that you will have to use -- to stop option parsing for gclient flags. To run `gclient sync --gclientfile=.gclient` and annotate got_v8_revision: `annotated_gclient.py --revision-mapping='{"src/v8": "got_v8_revision"}' -- sync --gclientfile=.gclient` """ from __future__ import print_function import contextlib import json import optparse import os import subprocess import sys import tempfile @contextlib.contextmanager def temp_filename(suffix='', prefix='tmp'): output_fd, output_file = tempfile.mkstemp(suffix=suffix, prefix=prefix) os.close(output_fd) yield output_file try: os.remove(output_file) except OSError as e: print('Error cleaning up temp file %s: %s' % (output_file, e)) def parse_got_revision(filename, revision_mapping): result = {} with open(filename) as f: data = json.load(f) for path, info in data['solutions'].iteritems(): # gclient json paths always end with a slash path = path.rstrip('/') if path in revision_mapping: propname = revision_mapping[path] result[propname] = info['revision'] return result def emit_buildprops(got_revisions): for prop, revision in got_revisions.iteritems(): print('@@@SET_BUILD_PROPERTY@%s@%s@@@' % (prop, json.dumps(revision))) def main(): parser = optparse.OptionParser( description=('Runs gclient and annotates the output with any ' 'got_revisions.')) parser.add_option('--revision-mapping', default='{}', help='json dict of directory-to-property mappings.') parser.add_option('--suffix', default='gclient', help='tempfile suffix') opts, args = parser.parse_args() revision_mapping = json.loads(opts.revision_mapping) if not args: parser.error('Must provide arguments to gclient.') if any(a.startswith('--output-json') for a in args): parser.error('Can\'t call annotated_gclient with --output-json.') with temp_filename(opts.suffix) as f: cmd = ['gclient'] cmd.extend(args) cmd.extend(['--output-json', f]) p = subprocess.Popen(cmd) p.wait() if p.returncode == 0: revisions = parse_got_revision(f, revision_mapping) emit_buildprops(revisions) return p.returncode if __name__ == '__main__': sys.exit(main())