Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #!/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 """Wrap gclient calls with annotated output. | |
|
M-A Ruel
2013/11/20 01:46:01
Wraps :)
| |
| 7 | |
| 8 Note that you will have to use -- to stop option parsing for gclient flags. | |
| 9 | |
| 10 To run `gclient sync --gclientfile=.gclient` and annotate got_v8_revision: | |
| 11 `annotated_gclient.py --mapping='{"src/v8": "got_v8_revision"}' -- | |
| 12 sync --gclientfile=.gclient` | |
| 13 """ | |
| 14 | |
| 15 import contextlib | |
| 16 import json | |
| 17 import optparse | |
| 18 import os | |
| 19 import subprocess | |
| 20 import sys | |
| 21 import tempfile | |
| 22 | |
| 23 | |
| 24 @contextlib.contextmanager | |
| 25 def temp_filename(suffix): | |
|
M-A Ruel
2013/11/20 01:46:01
I think it'd be good to:
prefix=None, suffix=None
ghost stip (do not use)
2013/11/20 02:08:02
'tmp' and '' according to
http://docs.python.org/
| |
| 26 output_fd, output_file = tempfile.mkstemp(suffix) | |
| 27 os.close(output_fd) | |
| 28 | |
| 29 yield output_file | |
| 30 | |
| 31 try: | |
| 32 os.remove(output_file) | |
| 33 except OSError as e: | |
| 34 print 'Error cleaning up temp file %s: %s' % (output_file, e) | |
| 35 | |
| 36 | |
| 37 def parse_got_revision(filename, revision_mapping): | |
| 38 result = {} | |
| 39 with open(filename) as f: | |
| 40 data = json.load(f) | |
| 41 | |
| 42 for path, info in data['solutions'].iteritems(): | |
| 43 # gclient json paths always end with a slash | |
| 44 path = path.rstrip('/') | |
| 45 if path in revision_mapping: | |
| 46 propname = revision_mapping[path] | |
| 47 result[propname] = info['revision'] | |
| 48 | |
| 49 return result | |
| 50 | |
| 51 | |
| 52 def emit_buildprops(got_revisions): | |
| 53 for prop, revision in got_revisions.iteritems(): | |
| 54 print '@@@SET_BUILD_PROPERTY@%s@%s@@@' % (prop, str(revision)) | |
|
M-A Ruel
2013/11/20 01:46:01
str() is not necessary.
| |
| 55 | |
| 56 | |
| 57 def main(): | |
| 58 parser = optparse.OptionParser( | |
| 59 description=('Runs gclient and annotates the output with any ' | |
| 60 'got_revisions.')) | |
| 61 parser.add_option('--revision-mapping', default='{}', | |
| 62 help='json dict of directory-to-property mappings.') | |
| 63 parser.add_option('--suffix', default='gclient', | |
| 64 help='tempfile suffix') | |
| 65 opts, args = parser.parse_args() | |
| 66 | |
| 67 revision_mapping = json.loads(opts.revision_mapping) | |
| 68 | |
| 69 if not args: | |
| 70 parser.error('Must provide arguments to gclient.') | |
| 71 | |
| 72 if any(a.startswith('--output-json') for a in args): | |
| 73 parser.error('Can\'t call annotated_gclient with --output-json.') | |
| 74 | |
| 75 with temp_filename(opts.suffix) as f: | |
| 76 cmd = ['gclient'] | |
| 77 cmd.extend(args) | |
| 78 cmd.extend(['--output-json', f]) | |
| 79 p = subprocess.Popen(cmd) | |
| 80 p.wait() | |
| 81 | |
| 82 if p.returncode == 0: | |
| 83 revisions = parse_got_revision(f, revision_mapping) | |
| 84 emit_buildprops(revisions) | |
| 85 return p.returncode | |
| 86 | |
|
M-A Ruel
2013/11/20 01:46:01
2 lines
ghost stip (do not use)
2013/11/20 02:08:02
good catch
| |
| 87 if __name__ == '__main__': | |
| 88 sys.exit(main()) | |
| OLD | NEW |