OLD | NEW |
| (Empty) |
1 #!/usr/bin/env python | |
2 # Copyright 2016 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 """ A collator for Mojo Application Manifests """ | |
7 | |
8 import argparse | |
9 import json | |
10 import os | |
11 import shutil | |
12 import sys | |
13 import urlparse | |
14 | |
15 eater_relative = '../../../../../tools/json_comment_eater' | |
16 eater_relative = os.path.join(os.path.abspath(__file__), eater_relative) | |
17 sys.path.insert(0, os.path.normpath(eater_relative)) | |
18 try: | |
19 import json_comment_eater | |
20 finally: | |
21 sys.path.pop(0) | |
22 | |
23 def ParseJSONFile(filename): | |
24 with open(filename) as json_file: | |
25 try: | |
26 return json.loads(json_comment_eater.Nom(json_file.read())) | |
27 except ValueError: | |
28 print "%s is not a valid JSON document" % filename | |
29 return None | |
30 | |
31 def MergeDicts(left, right): | |
32 for k, v in right.iteritems(): | |
33 if k not in left: | |
34 left[k] = v | |
35 else: | |
36 if isinstance(v, dict): | |
37 assert isinstance(left[k], dict) | |
38 MergeDicts(left[k], v) | |
39 elif isinstance(v, list): | |
40 assert isinstance(left[k], list) | |
41 left[k].extend(v) | |
42 else: | |
43 raise "Refusing to merge conflicting non-collection values." | |
44 return left | |
45 | |
46 | |
47 def MergeBaseManifest(parent, base): | |
48 MergeDicts(parent["capabilities"], base["capabilities"]) | |
49 | |
50 if "applications" in base: | |
51 if "applications" not in parent: | |
52 parent["applications"] = [] | |
53 parent["applications"].extend(base["applications"]) | |
54 | |
55 if "process-group" in base: | |
56 parent["process-group"] = base["process-group"] | |
57 | |
58 | |
59 def main(): | |
60 parser = argparse.ArgumentParser( | |
61 description="Collate Mojo application manifests.") | |
62 parser.add_argument("--parent") | |
63 parser.add_argument("--output") | |
64 parser.add_argument("--application-name") | |
65 parser.add_argument("--base-manifest", default=None) | |
66 args, children = parser.parse_known_args() | |
67 | |
68 parent = ParseJSONFile(args.parent) | |
69 if parent == None: | |
70 return 1 | |
71 | |
72 if args.base_manifest: | |
73 base = ParseJSONFile(args.base_manifest) | |
74 if base == None: | |
75 return 1 | |
76 MergeBaseManifest(parent, base) | |
77 | |
78 app_path = parent['name'].split(':')[1] | |
79 if app_path.startswith('//'): | |
80 raise ValueError("Application name path component '%s' must not start " \ | |
81 "with //" % app_path) | |
82 | |
83 if args.application_name != app_path: | |
84 raise ValueError("Application name '%s' specified in build file does not " \ | |
85 "match application name '%s' specified in manifest." % | |
86 (args.application_name, app_path)) | |
87 | |
88 applications = [] | |
89 for child in children: | |
90 application = ParseJSONFile(child) | |
91 if application == None: | |
92 return 1 | |
93 applications.append(application) | |
94 | |
95 if len(applications) > 0: | |
96 parent['applications'] = applications | |
97 | |
98 with open(args.output, 'w') as output_file: | |
99 json.dump(parent, output_file) | |
100 | |
101 return 0 | |
102 | |
103 if __name__ == "__main__": | |
104 sys.exit(main()) | |
OLD | NEW |