Chromium Code Reviews| Index: third_party/WebKit/Source/platform/inspector_protocol/generate-inspector-protocol-version |
| diff --git a/third_party/WebKit/Source/platform/inspector_protocol/generate-inspector-protocol-version b/third_party/WebKit/Source/platform/inspector_protocol/generate-inspector-protocol-version |
| index 8fce249d1bd081204f9ff2780f0de21d8767da88..f3bc660650c7d9023504a62fc642200660264d53 100755 |
| --- a/third_party/WebKit/Source/platform/inspector_protocol/generate-inspector-protocol-version |
| +++ b/third_party/WebKit/Source/platform/inspector_protocol/generate-inspector-protocol-version |
| @@ -45,10 +45,18 @@ |
| # |
| # Adding --show_changes to the command line prints out a list of valid public API changes. |
| +import collections |
| +import copy |
| import os.path |
| +import optparse |
| import re |
| import sys |
| +try: |
| + import json |
| +except ImportError: |
| + import simplejson as json |
| + |
| def list_to_map(items, key): |
| result = {} |
| for item in items: |
| @@ -56,21 +64,25 @@ def list_to_map(items, key): |
| result[item[key]] = item |
| return result |
| + |
| def named_list_to_map(container, name, key): |
| if name in container: |
| return list_to_map(container[name], key) |
| return {} |
| + |
| def removed(reverse): |
| if reverse: |
| return "added" |
| return "removed" |
| + |
| def required(reverse): |
| if reverse: |
| return "optional" |
| return "required" |
| + |
| def compare_schemas(schema_1, schema_2, reverse): |
| errors = [] |
| types_1 = normalize_types_in_schema(schema_1) |
| @@ -87,6 +99,7 @@ def compare_schemas(schema_1, schema_2, reverse): |
| compare_domains(domain_1, domains_by_name_2[name], types_1, types_2, errors, reverse) |
| return errors |
| + |
| def compare_domains(domain_1, domain_2, types_map_1, types_map_2, errors, reverse): |
| domain_name = domain_1["domain"] |
| commands_1 = named_list_to_map(domain_1, "commands", "name") |
| @@ -107,6 +120,7 @@ def compare_domains(domain_1, domain_2, types_map_1, types_map_2, errors, revers |
| continue |
| compare_events(domain_name, event_1, events_2[name], types_map_1, types_map_2, errors, reverse) |
| + |
| def compare_commands(domain_name, command_1, command_2, types_map_1, types_map_2, errors, reverse): |
| context = domain_name + "." + command_1["name"] |
| @@ -119,12 +133,14 @@ def compare_commands(domain_name, command_1, command_2, types_map_1, types_map_2 |
| returns_2 = named_list_to_map(command_2, "returns", "name") |
| compare_params_list(context, "response parameter", returns_1, returns_2, types_map_1, types_map_2, 0, errors, reverse) |
| + |
| def compare_events(domain_name, event_1, event_2, types_map_1, types_map_2, errors, reverse): |
| context = domain_name + "." + event_1["name"] |
| params_1 = named_list_to_map(event_1, "parameters", "name") |
| params_2 = named_list_to_map(event_2, "parameters", "name") |
| compare_params_list(context, "parameter", params_1, params_2, types_map_1, types_map_2, 0, errors, reverse) |
| + |
| def compare_params_list(context, kind, params_1, params_2, types_map_1, types_map_2, depth, errors, reverse): |
| for name in params_1: |
| param_1 = params_1[name] |
| @@ -141,6 +157,7 @@ def compare_params_list(context, kind, params_1, params_2, types_map_1, types_ma |
| type_2 = extract_type(param_2, types_map_2, errors) |
| compare_types(context + "." + name, kind, type_1, type_2, types_map_1, types_map_2, depth, errors, reverse) |
| + |
| def compare_types(context, kind, type_1, type_2, types_map_1, types_map_2, depth, errors, reverse): |
| if depth > 10: |
| return |
| @@ -165,6 +182,7 @@ def compare_types(context, kind, type_1, type_2, types_map_1, types_map_2, depth |
| item_type_2 = extract_type(type_2["items"], types_map_2, errors) |
| compare_types(context, kind, item_type_1, item_type_2, types_map_1, types_map_2, depth + 1, errors, reverse) |
| + |
| def extract_type(typed_object, types_map, errors): |
| if "type" in typed_object: |
| result = { "id": "<transient>", "type": typed_object["type"] } |
| @@ -180,6 +198,7 @@ def extract_type(typed_object, types_map, errors): |
| types_map[ref] = { "id": "<transient>", "type": "object" } |
| return types_map[ref] |
| + |
| def normalize_types_in_schema(schema): |
| types = {} |
| for domain in schema: |
| @@ -187,6 +206,7 @@ def normalize_types_in_schema(schema): |
| normalize_types(domain, domain_name, types) |
| return types |
| + |
| def normalize_types(obj, domain_name, types): |
| if isinstance(obj, list): |
| for item in obj: |
| @@ -201,12 +221,22 @@ def normalize_types(obj, domain_name, types): |
| else: |
| normalize_types(value, domain_name, types) |
| -def load_json(filename): |
| - input_file = open(filename, "r") |
| + |
| +def load_domain(file, domains): |
| + if not os.path.isfile(file): |
| + return |
| + input_file = open(file, "r") |
| json_string = input_file.read() |
| - json_string = re.sub(":\s*true", ": True", json_string) |
| - json_string = re.sub(":\s*false", ": False", json_string) |
| - return eval(json_string) |
| + parsed_json = json.loads(json_string, object_pairs_hook=collections.OrderedDict) |
| + domains.append(parsed_json) |
| + |
| + |
| +def load_domains(folder, domains): |
| + for f in os.listdir(folder): |
| + filename = os.path.join(folder, f) |
| + if filename.endswith(".json") and os.path.isfile(filename): |
| + load_domain(filename, domains) |
| + |
| def self_test(): |
| def create_test_schema_1(): |
| @@ -392,72 +422,67 @@ def self_test(): |
| compare_schemas(create_test_schema_2(), create_test_schema_1(), True))) |
| + |
| +def load_domains_and_baselines(folder, domains, baseline_domains): |
| + load_domains(os.path.normpath(folder + "/protocol"), domains) |
| + for domain in domains: |
| + version = "%s.%s" % (domain["version"]["major"], domain["version"]["minor"]) |
| + domain_path = folder + "/protocol-" + version + "/" + domain["domain"] + ".json" |
| + load_domain(os.path.normpath(domain_path), baseline_domains) |
| + |
| + |
| def main(): |
| if not self_test(): |
| sys.stderr.write("Self-test failed") |
| return 1 |
| - if len(sys.argv) < 4 or sys.argv[1] != "-o": |
| - sys.stderr.write("Usage: %s -o OUTPUT_FILE INPUT_FILE [--show-changes]\n" % sys.argv[0]) |
| + cmdline_parser = optparse.OptionParser() |
| + cmdline_parser.add_option("--show_changes") |
| + cmdline_parser.add_option("--o") |
| + arg_options, arg_values = cmdline_parser.parse_args() |
| + |
| + if len(arg_values) < 1 or not arg_options.o: |
| + sys.stderr.write("Usage: %s --o OUTPUT_FILE [--show_changes] PROTOCOL_FOLDER1 ?PROTOCOL_FOLDER2 \n" % sys.argv[0]) |
| return 1 |
| - output_path = sys.argv[2] |
| + output_path = arg_options.o |
| output_file = open(output_path, "w") |
| - input_path = sys.argv[3] |
| - dir_name = os.path.dirname(input_path) |
| - schema = load_json(input_path) |
| + domains = [] |
| + baseline_domains = [] |
| + load_domains_and_baselines(arg_values[0], domains, baseline_domains) |
| + if len(arg_values) > 1: |
| + load_domains_and_baselines(arg_values[1], domains, baseline_domains) |
| - major = schema["version"]["major"] |
| - minor = schema["version"]["minor"] |
| - version = "%s.%s" % (major, minor) |
| - if len(dir_name) == 0: |
| - dir_name = "." |
| - baseline_path = os.path.normpath(dir_name + "/Inspector-" + version + ".json") |
| - baseline_schema = load_json(baseline_path) |
| + domains_copy = copy.deepcopy(domains) |
|
dgozman
2016/06/03 02:24:03
deepcopy inside compare_schemas
pfeldman
2016/06/03 17:07:32
Done.
|
| + baseline_domains_copy = copy.deepcopy(baseline_domains) |
| + if arg_options.show_changes: |
| + domains_copy_2 = copy.deepcopy(domains) |
| + baseline_domains_copy_2 = copy.deepcopy(baseline_domains) |
| expected_errors = [ |
| "Debugger.globalObjectCleared: event has been removed" |
| ] |
| - errors = compare_schemas(baseline_schema["domains"], schema["domains"], False) |
| + errors = compare_schemas(baseline_domains, domains, False) |
| unexpected_errors = [] |
| for i in range(len(errors)): |
| if errors[i] not in expected_errors: |
| unexpected_errors.append(errors[i]) |
| if len(unexpected_errors) > 0: |
| - sys.stderr.write(" Compatibility with %s: FAILED\n" % version) |
| + sys.stderr.write(" Compatibility checks FAILED\n") |
| for error in unexpected_errors: |
| sys.stderr.write( " %s\n" % error) |
| return 1 |
| - if len(sys.argv) > 4 and sys.argv[4] == "--show-changes": |
| - changes = compare_schemas( |
| - load_json(input_path)["domains"], load_json(baseline_path)["domains"], True) |
| + if arg_options.show_changes: |
| + changes = compare_schemas(domains_copy_2, baseline_domains_copy_2, True) |
| if len(changes) > 0: |
| print " Public changes since %s:" % version |
| for change in changes: |
| print " %s" % change |
| - output_file.write(""" |
| -#ifndef InspectorProtocolVersion_h |
| -#define InspectorProtocolVersion_h |
| - |
| -#include "platform/inspector_protocol/String16.h" |
| - |
| -namespace blink { |
| - |
| -String inspectorProtocolVersion() { return "%s"; } |
| - |
| -int inspectorProtocolVersionMajor() { return %s; } |
| - |
| -int inspectorProtocolVersionMinor() { return %s; } |
| - |
| -} |
| - |
| -#endif // !defined(InspectorProtocolVersion_h) |
| -""" % (version, major, minor)) |
| - |
| + json.dump({"domains": domains_copy}, output_file, indent=4, sort_keys=False, separators=(',', ': ')) |
| output_file.close() |
| if __name__ == '__main__': |