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 |