| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """ A collator for Service Manifests """ | 6 """ A collator for Service Manifests """ |
| 7 | 7 |
| 8 import argparse | 8 import argparse |
| 9 import json | 9 import json |
| 10 import os | 10 import os |
| 11 import shutil | 11 import shutil |
| 12 import sys | 12 import sys |
| 13 import urlparse | 13 import urlparse |
| 14 | 14 |
| 15 | 15 |
| 16 # Keys which are completely overridden by manifest overlays | 16 # Keys which are completely overridden by manifest overlays |
| 17 _MANIFEST_OVERLAY_OVERRIDE_KEYS = [ | 17 _MANIFEST_OVERLAY_OVERRIDE_KEYS = [ |
| 18 "display_name", | 18 "display_name", |
| 19 ] | 19 ] |
| 20 | 20 |
| 21 eater_relative = "../../../../../../tools/json_comment_eater" | 21 eater_relative = '../../../../../../tools/json_comment_eater' |
| 22 eater_relative = os.path.join(os.path.abspath(__file__), eater_relative) | 22 eater_relative = os.path.join(os.path.abspath(__file__), eater_relative) |
| 23 sys.path.insert(0, os.path.normpath(eater_relative)) | 23 sys.path.insert(0, os.path.normpath(eater_relative)) |
| 24 try: | 24 try: |
| 25 import json_comment_eater | 25 import json_comment_eater |
| 26 finally: | 26 finally: |
| 27 sys.path.pop(0) | 27 sys.path.pop(0) |
| 28 | 28 |
| 29 | 29 |
| 30 def ParseJSONFile(filename): | 30 def ParseJSONFile(filename): |
| 31 with open(filename) as json_file: | 31 with open(filename) as json_file: |
| (...skipping 27 matching lines...) Expand all Loading... |
| 59 if "services" in overlay: | 59 if "services" in overlay: |
| 60 if "services" not in manifest: | 60 if "services" not in manifest: |
| 61 manifest["services"] = [] | 61 manifest["services"] = [] |
| 62 manifest["services"].extend(overlay["services"]) | 62 manifest["services"].extend(overlay["services"]) |
| 63 | 63 |
| 64 for key in _MANIFEST_OVERLAY_OVERRIDE_KEYS: | 64 for key in _MANIFEST_OVERLAY_OVERRIDE_KEYS: |
| 65 if key in overlay: | 65 if key in overlay: |
| 66 manifest[key] = overlay[key] | 66 manifest[key] = overlay[key] |
| 67 | 67 |
| 68 | 68 |
| 69 def SanityCheckManifestServices(manifest): | |
| 70 """Ensures any given service name appears only once within a manifest.""" | |
| 71 known_services = set() | |
| 72 def has_no_dupes(root): | |
| 73 if "name" in root: | |
| 74 name = root["name"] | |
| 75 if name in known_services: | |
| 76 raise ValueError( | |
| 77 "Duplicate manifest entry found for service: %s" % name) | |
| 78 known_services.add(name) | |
| 79 if "services" not in root: | |
| 80 return True | |
| 81 return all(has_no_dupes(service) for service in root["services"]) | |
| 82 return has_no_dupes(manifest) | |
| 83 | |
| 84 | |
| 85 def main(): | 69 def main(): |
| 86 parser = argparse.ArgumentParser( | 70 parser = argparse.ArgumentParser( |
| 87 description="Collate Service Manifests.") | 71 description="Collate Service Manifests.") |
| 88 parser.add_argument("--parent") | 72 parser.add_argument("--parent") |
| 89 parser.add_argument("--output") | 73 parser.add_argument("--output") |
| 90 parser.add_argument("--name") | 74 parser.add_argument("--name") |
| 91 parser.add_argument("--pretty", action="store_true") | 75 parser.add_argument("--pretty", action="store_true") |
| 92 parser.add_argument("--overlays", nargs="+", dest="overlays", default=[]) | 76 parser.add_argument("--overlays", nargs="+", dest="overlays", default=[]) |
| 93 parser.add_argument("--packaged-services", nargs="+", | 77 parser.add_argument("--packaged-services", nargs="+", |
| 94 dest="packaged_services", default=[]) | 78 dest="packaged_services", default=[]) |
| 95 args, _ = parser.parse_known_args() | 79 args, _ = parser.parse_known_args() |
| 96 | 80 |
| 97 parent = ParseJSONFile(args.parent) | 81 parent = ParseJSONFile(args.parent) |
| 98 | 82 |
| 99 service_name = parent["name"] if "name" in parent else "" | 83 service_path = parent['name'] |
| 100 if args.name and args.name != service_name: | 84 if args.name and args.name != service_path: |
| 101 raise ValueError("Service name '%s' specified in build file does not " \ | 85 raise ValueError("Service name '%s' specified in build file does not " \ |
| 102 "match name '%s' specified in manifest." % | 86 "match name '%s' specified in manifest." % |
| 103 (args.name, service_name)) | 87 (args.name, service_path)) |
| 104 | 88 |
| 105 packaged_services = [] | 89 packaged_services = [] |
| 106 for child_manifest in args.packaged_services: | 90 for child_manifest in args.packaged_services: |
| 107 packaged_services.append(ParseJSONFile(child_manifest)) | 91 packaged_services.append(ParseJSONFile(child_manifest)) |
| 108 | 92 |
| 109 if len(packaged_services) > 0: | 93 if len(packaged_services) > 0: |
| 110 if "services" not in parent: | 94 if 'services' not in parent: |
| 111 parent["services"] = packaged_services | 95 parent['services'] = packaged_services |
| 112 else: | 96 else: |
| 113 parent["services"].extend(packaged_services) | 97 parent['services'].extend(packaged_services) |
| 114 | 98 |
| 115 for overlay_path in args.overlays: | 99 for overlay_path in args.overlays: |
| 116 MergeManifestOverlay(parent, ParseJSONFile(overlay_path)) | 100 MergeManifestOverlay(parent, ParseJSONFile(overlay_path)) |
| 117 | 101 |
| 118 with open(args.output, "w") as output_file: | 102 with open(args.output, 'w') as output_file: |
| 119 json.dump(parent, output_file, indent=2 if args.pretty else -1) | 103 json.dump(parent, output_file, indent=2 if args.pretty else -1) |
| 120 | 104 |
| 121 # NOTE: We do the sanity check and possible failure *after* outputting the | |
| 122 # aggregate manifest so it's easier to inspect erroneous output. | |
| 123 SanityCheckManifestServices(parent) | |
| 124 | |
| 125 return 0 | 105 return 0 |
| 126 | 106 |
| 127 if __name__ == "__main__": | 107 if __name__ == "__main__": |
| 128 sys.exit(main()) | 108 sys.exit(main()) |
| OLD | NEW |