Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2011 Google Inc. All rights reserved. | 2 # Copyright (c) 2011 Google Inc. All rights reserved. |
| 3 # | 3 # |
| 4 # Redistribution and use in source and binary forms, with or without | 4 # Redistribution and use in source and binary forms, with or without |
| 5 # modification, are permitted provided that the following conditions are | 5 # modification, are permitted provided that the following conditions are |
| 6 # met: | 6 # met: |
| 7 # | 7 # |
| 8 # * Redistributions of source code must retain the above copyright | 8 # * Redistributions of source code must retain the above copyright |
| 9 # notice, this list of conditions and the following disclaimer. | 9 # notice, this list of conditions and the following disclaimer. |
| 10 # * Redistributions in binary form must reproduce the above | 10 # * Redistributions in binary form must reproduce the above |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 38 # - Required response parameter was removed or changed to optional | 38 # - Required response parameter was removed or changed to optional |
| 39 # - Event has been removed | 39 # - Event has been removed |
| 40 # - Required event parameter was removed or changed to optional | 40 # - Required event parameter was removed or changed to optional |
| 41 # - Parameter type has changed. | 41 # - Parameter type has changed. |
| 42 # | 42 # |
| 43 # For the parameters with composite types the above checks are also applied | 43 # For the parameters with composite types the above checks are also applied |
| 44 # recursively to every property of the type. | 44 # recursively to every property of the type. |
| 45 # | 45 # |
| 46 # Adding --show_changes to the command line prints out a list of valid public AP I changes. | 46 # Adding --show_changes to the command line prints out a list of valid public AP I changes. |
| 47 | 47 |
| 48 import collections | |
| 49 import copy | |
| 48 import os.path | 50 import os.path |
| 51 import optparse | |
| 49 import re | 52 import re |
| 50 import sys | 53 import sys |
| 51 | 54 |
| 55 try: | |
| 56 import json | |
| 57 except ImportError: | |
| 58 import simplejson as json | |
| 59 | |
| 52 def list_to_map(items, key): | 60 def list_to_map(items, key): |
| 53 result = {} | 61 result = {} |
| 54 for item in items: | 62 for item in items: |
| 55 if not "hidden" in item: | 63 if not "hidden" in item: |
| 56 result[item[key]] = item | 64 result[item[key]] = item |
| 57 return result | 65 return result |
| 58 | 66 |
| 67 | |
| 59 def named_list_to_map(container, name, key): | 68 def named_list_to_map(container, name, key): |
| 60 if name in container: | 69 if name in container: |
| 61 return list_to_map(container[name], key) | 70 return list_to_map(container[name], key) |
| 62 return {} | 71 return {} |
| 63 | 72 |
| 73 | |
| 64 def removed(reverse): | 74 def removed(reverse): |
| 65 if reverse: | 75 if reverse: |
| 66 return "added" | 76 return "added" |
| 67 return "removed" | 77 return "removed" |
| 68 | 78 |
| 79 | |
| 69 def required(reverse): | 80 def required(reverse): |
| 70 if reverse: | 81 if reverse: |
| 71 return "optional" | 82 return "optional" |
| 72 return "required" | 83 return "required" |
| 73 | 84 |
| 85 | |
| 74 def compare_schemas(schema_1, schema_2, reverse): | 86 def compare_schemas(schema_1, schema_2, reverse): |
| 75 errors = [] | 87 errors = [] |
| 76 types_1 = normalize_types_in_schema(schema_1) | 88 types_1 = normalize_types_in_schema(schema_1) |
| 77 types_2 = normalize_types_in_schema(schema_2) | 89 types_2 = normalize_types_in_schema(schema_2) |
| 78 | 90 |
| 79 domains_by_name_1 = list_to_map(schema_1, "domain") | 91 domains_by_name_1 = list_to_map(schema_1, "domain") |
| 80 domains_by_name_2 = list_to_map(schema_2, "domain") | 92 domains_by_name_2 = list_to_map(schema_2, "domain") |
| 81 | 93 |
| 82 for name in domains_by_name_1: | 94 for name in domains_by_name_1: |
| 83 domain_1 = domains_by_name_1[name] | 95 domain_1 = domains_by_name_1[name] |
| 84 if not name in domains_by_name_2: | 96 if not name in domains_by_name_2: |
| 85 errors.append("%s: domain has been %s" % (name, removed(reverse))) | 97 errors.append("%s: domain has been %s" % (name, removed(reverse))) |
| 86 continue | 98 continue |
| 87 compare_domains(domain_1, domains_by_name_2[name], types_1, types_2, err ors, reverse) | 99 compare_domains(domain_1, domains_by_name_2[name], types_1, types_2, err ors, reverse) |
| 88 return errors | 100 return errors |
| 89 | 101 |
| 102 | |
| 90 def compare_domains(domain_1, domain_2, types_map_1, types_map_2, errors, revers e): | 103 def compare_domains(domain_1, domain_2, types_map_1, types_map_2, errors, revers e): |
| 91 domain_name = domain_1["domain"] | 104 domain_name = domain_1["domain"] |
| 92 commands_1 = named_list_to_map(domain_1, "commands", "name") | 105 commands_1 = named_list_to_map(domain_1, "commands", "name") |
| 93 commands_2 = named_list_to_map(domain_2, "commands", "name") | 106 commands_2 = named_list_to_map(domain_2, "commands", "name") |
| 94 for name in commands_1: | 107 for name in commands_1: |
| 95 command_1 = commands_1[name] | 108 command_1 = commands_1[name] |
| 96 if not name in commands_2: | 109 if not name in commands_2: |
| 97 errors.append("%s.%s: command has been %s" % (domain_1["domain"], na me, removed(reverse))) | 110 errors.append("%s.%s: command has been %s" % (domain_1["domain"], na me, removed(reverse))) |
| 98 continue | 111 continue |
| 99 compare_commands(domain_name, command_1, commands_2[name], types_map_1, types_map_2, errors, reverse) | 112 compare_commands(domain_name, command_1, commands_2[name], types_map_1, types_map_2, errors, reverse) |
| 100 | 113 |
| 101 events_1 = named_list_to_map(domain_1, "events", "name") | 114 events_1 = named_list_to_map(domain_1, "events", "name") |
| 102 events_2 = named_list_to_map(domain_2, "events", "name") | 115 events_2 = named_list_to_map(domain_2, "events", "name") |
| 103 for name in events_1: | 116 for name in events_1: |
| 104 event_1 = events_1[name] | 117 event_1 = events_1[name] |
| 105 if not name in events_2: | 118 if not name in events_2: |
| 106 errors.append("%s.%s: event has been %s" % (domain_1["domain"], name , removed(reverse))) | 119 errors.append("%s.%s: event has been %s" % (domain_1["domain"], name , removed(reverse))) |
| 107 continue | 120 continue |
| 108 compare_events(domain_name, event_1, events_2[name], types_map_1, types_ map_2, errors, reverse) | 121 compare_events(domain_name, event_1, events_2[name], types_map_1, types_ map_2, errors, reverse) |
| 109 | 122 |
| 123 | |
| 110 def compare_commands(domain_name, command_1, command_2, types_map_1, types_map_2 , errors, reverse): | 124 def compare_commands(domain_name, command_1, command_2, types_map_1, types_map_2 , errors, reverse): |
| 111 context = domain_name + "." + command_1["name"] | 125 context = domain_name + "." + command_1["name"] |
| 112 | 126 |
| 113 params_1 = named_list_to_map(command_1, "parameters", "name") | 127 params_1 = named_list_to_map(command_1, "parameters", "name") |
| 114 params_2 = named_list_to_map(command_2, "parameters", "name") | 128 params_2 = named_list_to_map(command_2, "parameters", "name") |
| 115 # Note the reversed order: we allow removing but forbid adding parameters. | 129 # Note the reversed order: we allow removing but forbid adding parameters. |
| 116 compare_params_list(context, "parameter", params_2, params_1, types_map_2, t ypes_map_1, 0, errors, not reverse) | 130 compare_params_list(context, "parameter", params_2, params_1, types_map_2, t ypes_map_1, 0, errors, not reverse) |
| 117 | 131 |
| 118 returns_1 = named_list_to_map(command_1, "returns", "name") | 132 returns_1 = named_list_to_map(command_1, "returns", "name") |
| 119 returns_2 = named_list_to_map(command_2, "returns", "name") | 133 returns_2 = named_list_to_map(command_2, "returns", "name") |
| 120 compare_params_list(context, "response parameter", returns_1, returns_2, typ es_map_1, types_map_2, 0, errors, reverse) | 134 compare_params_list(context, "response parameter", returns_1, returns_2, typ es_map_1, types_map_2, 0, errors, reverse) |
| 121 | 135 |
| 136 | |
| 122 def compare_events(domain_name, event_1, event_2, types_map_1, types_map_2, erro rs, reverse): | 137 def compare_events(domain_name, event_1, event_2, types_map_1, types_map_2, erro rs, reverse): |
| 123 context = domain_name + "." + event_1["name"] | 138 context = domain_name + "." + event_1["name"] |
| 124 params_1 = named_list_to_map(event_1, "parameters", "name") | 139 params_1 = named_list_to_map(event_1, "parameters", "name") |
| 125 params_2 = named_list_to_map(event_2, "parameters", "name") | 140 params_2 = named_list_to_map(event_2, "parameters", "name") |
| 126 compare_params_list(context, "parameter", params_1, params_2, types_map_1, t ypes_map_2, 0, errors, reverse) | 141 compare_params_list(context, "parameter", params_1, params_2, types_map_1, t ypes_map_2, 0, errors, reverse) |
| 127 | 142 |
| 143 | |
| 128 def compare_params_list(context, kind, params_1, params_2, types_map_1, types_ma p_2, depth, errors, reverse): | 144 def compare_params_list(context, kind, params_1, params_2, types_map_1, types_ma p_2, depth, errors, reverse): |
| 129 for name in params_1: | 145 for name in params_1: |
| 130 param_1 = params_1[name] | 146 param_1 = params_1[name] |
| 131 if not name in params_2: | 147 if not name in params_2: |
| 132 if not "optional" in param_1: | 148 if not "optional" in param_1: |
| 133 errors.append("%s.%s: required %s has been %s" % (context, name, kind, removed(reverse))) | 149 errors.append("%s.%s: required %s has been %s" % (context, name, kind, removed(reverse))) |
| 134 continue | 150 continue |
| 135 | 151 |
| 136 param_2 = params_2[name] | 152 param_2 = params_2[name] |
| 137 if param_2 and "optional" in param_2 and not "optional" in param_1: | 153 if param_2 and "optional" in param_2 and not "optional" in param_1: |
| 138 errors.append("%s.%s: %s %s is now %s" % (context, name, required(re verse), kind, required(not reverse))) | 154 errors.append("%s.%s: %s %s is now %s" % (context, name, required(re verse), kind, required(not reverse))) |
| 139 continue | 155 continue |
| 140 type_1 = extract_type(param_1, types_map_1, errors) | 156 type_1 = extract_type(param_1, types_map_1, errors) |
| 141 type_2 = extract_type(param_2, types_map_2, errors) | 157 type_2 = extract_type(param_2, types_map_2, errors) |
| 142 compare_types(context + "." + name, kind, type_1, type_2, types_map_1, t ypes_map_2, depth, errors, reverse) | 158 compare_types(context + "." + name, kind, type_1, type_2, types_map_1, t ypes_map_2, depth, errors, reverse) |
| 143 | 159 |
| 160 | |
| 144 def compare_types(context, kind, type_1, type_2, types_map_1, types_map_2, depth , errors, reverse): | 161 def compare_types(context, kind, type_1, type_2, types_map_1, types_map_2, depth , errors, reverse): |
| 145 if depth > 10: | 162 if depth > 10: |
| 146 return | 163 return |
| 147 | 164 |
| 148 base_type_1 = type_1["type"] | 165 base_type_1 = type_1["type"] |
| 149 base_type_2 = type_2["type"] | 166 base_type_2 = type_2["type"] |
| 150 | 167 |
| 151 if base_type_1 != base_type_2: | 168 if base_type_1 != base_type_2: |
| 152 errors.append("%s: %s base type mismatch, '%s' vs '%s'" % (context, kind , base_type_1, base_type_2)) | 169 errors.append("%s: %s base type mismatch, '%s' vs '%s'" % (context, kind , base_type_1, base_type_2)) |
| 153 elif base_type_1 == "object": | 170 elif base_type_1 == "object": |
| 154 params_1 = named_list_to_map(type_1, "properties", "name") | 171 params_1 = named_list_to_map(type_1, "properties", "name") |
| 155 params_2 = named_list_to_map(type_2, "properties", "name") | 172 params_2 = named_list_to_map(type_2, "properties", "name") |
| 156 # If both parameters have the same named type use it in the context. | 173 # If both parameters have the same named type use it in the context. |
| 157 if "id" in type_1 and "id" in type_2 and type_1["id"] == type_2["id"]: | 174 if "id" in type_1 and "id" in type_2 and type_1["id"] == type_2["id"]: |
| 158 type_name = type_1["id"] | 175 type_name = type_1["id"] |
| 159 else: | 176 else: |
| 160 type_name = "<object>" | 177 type_name = "<object>" |
| 161 context += " %s->%s" % (kind, type_name) | 178 context += " %s->%s" % (kind, type_name) |
| 162 compare_params_list(context, "property", params_1, params_2, types_map_1 , types_map_2, depth + 1, errors, reverse) | 179 compare_params_list(context, "property", params_1, params_2, types_map_1 , types_map_2, depth + 1, errors, reverse) |
| 163 elif base_type_1 == "array": | 180 elif base_type_1 == "array": |
| 164 item_type_1 = extract_type(type_1["items"], types_map_1, errors) | 181 item_type_1 = extract_type(type_1["items"], types_map_1, errors) |
| 165 item_type_2 = extract_type(type_2["items"], types_map_2, errors) | 182 item_type_2 = extract_type(type_2["items"], types_map_2, errors) |
| 166 compare_types(context, kind, item_type_1, item_type_2, types_map_1, type s_map_2, depth + 1, errors, reverse) | 183 compare_types(context, kind, item_type_1, item_type_2, types_map_1, type s_map_2, depth + 1, errors, reverse) |
| 167 | 184 |
| 185 | |
| 168 def extract_type(typed_object, types_map, errors): | 186 def extract_type(typed_object, types_map, errors): |
| 169 if "type" in typed_object: | 187 if "type" in typed_object: |
| 170 result = { "id": "<transient>", "type": typed_object["type"] } | 188 result = { "id": "<transient>", "type": typed_object["type"] } |
| 171 if typed_object["type"] == "object": | 189 if typed_object["type"] == "object": |
| 172 result["properties"] = [] | 190 result["properties"] = [] |
| 173 elif typed_object["type"] == "array": | 191 elif typed_object["type"] == "array": |
| 174 result["items"] = typed_object["items"] | 192 result["items"] = typed_object["items"] |
| 175 return result | 193 return result |
| 176 elif "$ref" in typed_object: | 194 elif "$ref" in typed_object: |
| 177 ref = typed_object["$ref"] | 195 ref = typed_object["$ref"] |
| 178 if not ref in types_map: | 196 if not ref in types_map: |
| 179 errors.append("Can not resolve type: %s" % ref) | 197 errors.append("Can not resolve type: %s" % ref) |
| 180 types_map[ref] = { "id": "<transient>", "type": "object" } | 198 types_map[ref] = { "id": "<transient>", "type": "object" } |
| 181 return types_map[ref] | 199 return types_map[ref] |
| 182 | 200 |
| 201 | |
| 183 def normalize_types_in_schema(schema): | 202 def normalize_types_in_schema(schema): |
| 184 types = {} | 203 types = {} |
| 185 for domain in schema: | 204 for domain in schema: |
| 186 domain_name = domain["domain"] | 205 domain_name = domain["domain"] |
| 187 normalize_types(domain, domain_name, types) | 206 normalize_types(domain, domain_name, types) |
| 188 return types | 207 return types |
| 189 | 208 |
| 209 | |
| 190 def normalize_types(obj, domain_name, types): | 210 def normalize_types(obj, domain_name, types): |
| 191 if isinstance(obj, list): | 211 if isinstance(obj, list): |
| 192 for item in obj: | 212 for item in obj: |
| 193 normalize_types(item, domain_name, types) | 213 normalize_types(item, domain_name, types) |
| 194 elif isinstance(obj, dict): | 214 elif isinstance(obj, dict): |
| 195 for key, value in obj.items(): | 215 for key, value in obj.items(): |
| 196 if key == "$ref" and value.find(".") == -1: | 216 if key == "$ref" and value.find(".") == -1: |
| 197 obj[key] = "%s.%s" % (domain_name, value) | 217 obj[key] = "%s.%s" % (domain_name, value) |
| 198 elif key == "id": | 218 elif key == "id": |
| 199 obj[key] = "%s.%s" % (domain_name, value) | 219 obj[key] = "%s.%s" % (domain_name, value) |
| 200 types[obj[key]] = obj | 220 types[obj[key]] = obj |
| 201 else: | 221 else: |
| 202 normalize_types(value, domain_name, types) | 222 normalize_types(value, domain_name, types) |
| 203 | 223 |
| 204 def load_json(filename): | 224 |
| 205 input_file = open(filename, "r") | 225 def load_domain(file, domains): |
| 226 if not os.path.isfile(file): | |
| 227 return | |
| 228 input_file = open(file, "r") | |
| 206 json_string = input_file.read() | 229 json_string = input_file.read() |
| 207 json_string = re.sub(":\s*true", ": True", json_string) | 230 parsed_json = json.loads(json_string, object_pairs_hook=collections.OrderedD ict) |
| 208 json_string = re.sub(":\s*false", ": False", json_string) | 231 domains.append(parsed_json) |
| 209 return eval(json_string) | 232 |
| 233 | |
| 234 def load_domains(folder, domains): | |
| 235 for f in os.listdir(folder): | |
| 236 filename = os.path.join(folder, f) | |
| 237 if filename.endswith(".json") and os.path.isfile(filename): | |
| 238 load_domain(filename, domains) | |
| 239 | |
| 210 | 240 |
| 211 def self_test(): | 241 def self_test(): |
| 212 def create_test_schema_1(): | 242 def create_test_schema_1(): |
| 213 return [ | 243 return [ |
| 214 { | 244 { |
| 215 "domain": "Network", | 245 "domain": "Network", |
| 216 "types": [ | 246 "types": [ |
| 217 { | 247 { |
| 218 "id": "LoaderId", | 248 "id": "LoaderId", |
| 219 "type": "string" | 249 "type": "string" |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 385 def errors_match(expected, actual): | 415 def errors_match(expected, actual): |
| 386 return (is_subset(actual, expected, "Unexpected") and | 416 return (is_subset(actual, expected, "Unexpected") and |
| 387 is_subset(expected, actual, "Missing")) | 417 is_subset(expected, actual, "Missing")) |
| 388 | 418 |
| 389 return (errors_match(expected_errors, | 419 return (errors_match(expected_errors, |
| 390 compare_schemas(create_test_schema_1(), create_test_sch ema_2(), False)) and | 420 compare_schemas(create_test_schema_1(), create_test_sch ema_2(), False)) and |
| 391 errors_match(expected_errors_reverse, | 421 errors_match(expected_errors_reverse, |
| 392 compare_schemas(create_test_schema_2(), create_test_sch ema_1(), True))) | 422 compare_schemas(create_test_schema_2(), create_test_sch ema_1(), True))) |
| 393 | 423 |
| 394 | 424 |
| 425 | |
| 426 def load_domains_and_baselines(folder, domains, baseline_domains): | |
| 427 load_domains(os.path.normpath(folder + "/protocol"), domains) | |
| 428 for domain in domains: | |
| 429 version = "%s.%s" % (domain["version"]["major"], domain["version"]["mino r"]) | |
| 430 domain_path = folder + "/protocol-" + version + "/" + domain["domain"] + ".json" | |
| 431 load_domain(os.path.normpath(domain_path), baseline_domains) | |
| 432 | |
| 433 | |
| 395 def main(): | 434 def main(): |
| 396 if not self_test(): | 435 if not self_test(): |
| 397 sys.stderr.write("Self-test failed") | 436 sys.stderr.write("Self-test failed") |
| 398 return 1 | 437 return 1 |
| 399 | 438 |
| 400 if len(sys.argv) < 4 or sys.argv[1] != "-o": | 439 cmdline_parser = optparse.OptionParser() |
| 401 sys.stderr.write("Usage: %s -o OUTPUT_FILE INPUT_FILE [--show-changes]\n " % sys.argv[0]) | 440 cmdline_parser.add_option("--show_changes") |
| 441 cmdline_parser.add_option("--o") | |
| 442 arg_options, arg_values = cmdline_parser.parse_args() | |
| 443 | |
| 444 if len(arg_values) < 1 or not arg_options.o: | |
| 445 sys.stderr.write("Usage: %s --o OUTPUT_FILE [--show_changes] PROTOCOL_FO LDER1 ?PROTOCOL_FOLDER2 \n" % sys.argv[0]) | |
| 402 return 1 | 446 return 1 |
| 403 | 447 |
| 404 output_path = sys.argv[2] | 448 output_path = arg_options.o |
| 405 output_file = open(output_path, "w") | 449 output_file = open(output_path, "w") |
| 406 | 450 |
| 407 input_path = sys.argv[3] | 451 domains = [] |
| 408 dir_name = os.path.dirname(input_path) | 452 baseline_domains = [] |
| 409 schema = load_json(input_path) | 453 load_domains_and_baselines(arg_values[0], domains, baseline_domains) |
| 454 if len(arg_values) > 1: | |
| 455 load_domains_and_baselines(arg_values[1], domains, baseline_domains) | |
| 410 | 456 |
| 411 major = schema["version"]["major"] | 457 domains_copy = copy.deepcopy(domains) |
|
dgozman
2016/06/03 02:24:03
deepcopy inside compare_schemas
pfeldman
2016/06/03 17:07:32
Done.
| |
| 412 minor = schema["version"]["minor"] | 458 baseline_domains_copy = copy.deepcopy(baseline_domains) |
| 413 version = "%s.%s" % (major, minor) | 459 if arg_options.show_changes: |
| 414 if len(dir_name) == 0: | 460 domains_copy_2 = copy.deepcopy(domains) |
| 415 dir_name = "." | 461 baseline_domains_copy_2 = copy.deepcopy(baseline_domains) |
| 416 baseline_path = os.path.normpath(dir_name + "/Inspector-" + version + ".json ") | |
| 417 baseline_schema = load_json(baseline_path) | |
| 418 | 462 |
| 419 expected_errors = [ | 463 expected_errors = [ |
| 420 "Debugger.globalObjectCleared: event has been removed" | 464 "Debugger.globalObjectCleared: event has been removed" |
| 421 ] | 465 ] |
| 422 | 466 |
| 423 errors = compare_schemas(baseline_schema["domains"], schema["domains"], Fals e) | 467 errors = compare_schemas(baseline_domains, domains, False) |
| 424 unexpected_errors = [] | 468 unexpected_errors = [] |
| 425 for i in range(len(errors)): | 469 for i in range(len(errors)): |
| 426 if errors[i] not in expected_errors: | 470 if errors[i] not in expected_errors: |
| 427 unexpected_errors.append(errors[i]) | 471 unexpected_errors.append(errors[i]) |
| 428 if len(unexpected_errors) > 0: | 472 if len(unexpected_errors) > 0: |
| 429 sys.stderr.write(" Compatibility with %s: FAILED\n" % version) | 473 sys.stderr.write(" Compatibility checks FAILED\n") |
| 430 for error in unexpected_errors: | 474 for error in unexpected_errors: |
| 431 sys.stderr.write( " %s\n" % error) | 475 sys.stderr.write( " %s\n" % error) |
| 432 return 1 | 476 return 1 |
| 433 | 477 |
| 434 if len(sys.argv) > 4 and sys.argv[4] == "--show-changes": | 478 if arg_options.show_changes: |
| 435 changes = compare_schemas( | 479 changes = compare_schemas(domains_copy_2, baseline_domains_copy_2, True) |
| 436 load_json(input_path)["domains"], load_json(baseline_path)["domains" ], True) | |
| 437 if len(changes) > 0: | 480 if len(changes) > 0: |
| 438 print " Public changes since %s:" % version | 481 print " Public changes since %s:" % version |
| 439 for change in changes: | 482 for change in changes: |
| 440 print " %s" % change | 483 print " %s" % change |
| 441 | 484 |
| 442 output_file.write(""" | 485 json.dump({"domains": domains_copy}, output_file, indent=4, sort_keys=False, separators=(',', ': ')) |
| 443 #ifndef InspectorProtocolVersion_h | |
| 444 #define InspectorProtocolVersion_h | |
| 445 | |
| 446 #include "platform/inspector_protocol/String16.h" | |
| 447 | |
| 448 namespace blink { | |
| 449 | |
| 450 String inspectorProtocolVersion() { return "%s"; } | |
| 451 | |
| 452 int inspectorProtocolVersionMajor() { return %s; } | |
| 453 | |
| 454 int inspectorProtocolVersionMinor() { return %s; } | |
| 455 | |
| 456 } | |
| 457 | |
| 458 #endif // !defined(InspectorProtocolVersion_h) | |
| 459 """ % (version, major, minor)) | |
| 460 | |
| 461 output_file.close() | 486 output_file.close() |
| 462 | 487 |
| 463 if __name__ == '__main__': | 488 if __name__ == '__main__': |
| 464 sys.exit(main()) | 489 sys.exit(main()) |
| OLD | NEW |