diff --git a/build-tools/capi_parser/src/bin/config.py b/build-tools/capi_parser/src/bin/config.py index 3e6da60f84c29934f1f791790142d4ef88d73b38..b9f2a263eb40b6737094ff8524f902c709a5e10a 100644 --- a/build-tools/capi_parser/src/bin/config.py +++ b/build-tools/capi_parser/src/bin/config.py @@ -16,6 +16,7 @@ import enum from coreImpl.parser import parser from coreImpl.check import check +from coreImpl.diff import diff class ToolNameType(enum.Enum): @@ -46,7 +47,7 @@ def run_tools(options): if tool_name == ToolNameType["COLLECT"].value: parser.parser(options.parser_path) elif tool_name == ToolNameType["DIFF"].value: - print("开发中。。。") + diff.process_dir(options.diff_path_old, options.diff_path_new) elif tool_name == ToolNameType['CHECK'].value: check.curr_entry(options.parser_path) else: @@ -73,5 +74,20 @@ class Config(object): "required": True, "type": str, "help": "解析路径" + }, + { + "name": "--diff-path-old", + "abbr": "-old", + "required": False, + "type": str, + "help": "旧文件路径" + }, + { + "name": "--diff-path-new", + "abbr": "-new", + "required": False, + "type": str, + "help": "新文件路径" } + ] diff --git a/build-tools/capi_parser/src/coreImpl/diff/diff.py b/build-tools/capi_parser/src/coreImpl/diff/diff.py new file mode 100644 index 0000000000000000000000000000000000000000..dd32e0e1f725e247666ff55435fe03ce15152dd1 --- /dev/null +++ b/build-tools/capi_parser/src/coreImpl/diff/diff.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from coreImpl.parser.parser import parser_include_ast +from coreImpl.diff.diff_file import start_diff_file + + +def process_pr(pr_id): + print("开发中...") + + +def process_dir(old_dir, new_dir): + start_diff_file(old_dir, new_dir) + + +def get_dir_by_pr(pr: str): + return {"old": "", "new": ""} + + +def process_dir_diff(old_dir, new_dir): + diff_info_list = [] + return diff_info_list + + +def process_file_diff(old_file, new_file): + diff_info_list = [] + return diff_info_list + + +def get_parser_data(file_path): + root_start = file_path.split('sdk_c')[0] + root_path = f'{root_start}sdk_c' + parser_data = parser_include_ast(root_path, [file_path]) + return parser_data diff --git a/build-tools/capi_parser/src/coreImpl/diff/diff_file.py b/build-tools/capi_parser/src/coreImpl/diff/diff_file.py new file mode 100644 index 0000000000000000000000000000000000000000..74f97953e65d505615e95a8d4e1ebaf9ccd2b65e --- /dev/null +++ b/build-tools/capi_parser/src/coreImpl/diff/diff_file.py @@ -0,0 +1,185 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import hashlib +import json +import os + +import openpyxl as op + +from coreImpl.parser.parser import parser_include_ast +from coreImpl.diff.diff_processor_node import judgment_entrance +from typedef.diff.diff import OutputJson + +global_old_dir = '' +global_new_dir = '' +diff_info_list = [] + + +def start_diff_file(old_dir, new_dir): + result_info_list = global_assignment(old_dir, new_dir) + generate_excel(result_info_list) + result_json = result_to_json(result_info_list) + write_in_txt(result_json, r'./ndk_diff.txt') + print(result_json) + + +def generate_excel(result_info_list): + data = [] + for diff_info in result_info_list: + info_data = [] + info_data.append(diff_info.api_name) + info_data.append(diff_info.api_type) + info_data.append(diff_info.diff_type.name) + info_data.append(diff_info.diff_message) + info_data.append(diff_info.old_api_full_text) + info_data.append(diff_info.new_api_full_text) + result = '' + if (diff_info.is_compatible): + result = '是' + else: + result = '否' + info_data.append(result) + data.append(info_data) + wb = op.Workbook() + ws = wb['Sheet'] + ws.append(['api名称', '节点类型', '变更类型', '变更信息', '旧版节点内容', '新版节点内容', '兼容']) + for i in range(len(data)): + d = data[i][0], data[i][1], data[i][2], data[i][3], data[i][4], data[i][5], data[i][6] + ws.append(d) + wb.save('diff.xlsx') + + +def global_assignment(old_dir, new_dir): + global global_old_dir + global_old_dir = old_dir + global global_new_dir + global_new_dir = new_dir + do_diff(old_dir, new_dir) + return diff_info_list + + +def result_to_json(result_info_list): + result_json = [] + for diff_info in result_info_list: + result_json.append(OutputJson(diff_info)) + return json.dumps(result_json, default=lambda obj: obj.__dict__, indent=4) + + +def write_in_txt(check_result, output_path): + fs = open(output_path, 'w', encoding='utf-8') + fs.write(check_result) + fs.close() + + +def do_diff(old_dir, new_dir): + old_file_list = os.listdir(old_dir) + new_file_list = os.listdir(new_dir) + diff_list(old_file_list, new_file_list, old_dir, new_dir) + + +def get_file_md5(file_name): + md5 = hashlib.md5() + with open(file_name, 'rb') as file: + content = file.read() + md5.update(content) + return md5.hexdigest() + + +def get_file_ext(file_name): + return os.path.splitext(file_name)[1] + + +def diff_list(old_file_list, new_file_list, old_dir, new_dir): + all_list = set(old_file_list + new_file_list) + if len(all_list) == 0: + return + for target_file in all_list: + if (get_file_ext(target_file) != '.h' + and get_file_ext(target_file) != ''): + continue + if (target_file in old_file_list + and target_file not in new_file_list): + diff_file_path = os.path.join(old_dir, target_file) + if os.path.isdir(diff_file_path): + del_file(diff_file_path) + if (target_file in new_file_list + and target_file not in old_file_list): + diff_file_path = os.path.join(new_dir, target_file) + if os.path.isdir(diff_file_path): + add_file(diff_file_path) + get_same_file_diff(target_file, old_file_list, new_file_list, old_dir, new_dir) + + +def get_same_file_diff(target_file, old_file_list, new_file_list, old_dir, new_dir): + if (target_file in old_file_list + and target_file in new_file_list): + if (os.path.isdir(os.path.join(old_dir, target_file)) + and os.path.isdir(os.path.join(new_dir, target_file))): + old_child_dir = os.path.join(old_dir, target_file) + new_child_dir = os.path.join(new_dir, target_file) + do_diff(old_child_dir, new_child_dir) + if (os.path.isfile(os.path.join(old_dir, target_file)) + and os.path.isfile(os.path.join(new_dir, target_file))): + old_target_file = os.path.join(old_dir, target_file) + new_target_file = os.path.join(new_dir, target_file) + if get_file_md5(old_target_file) != get_file_md5(new_target_file): + get_file_result_diff(old_target_file, new_target_file) + + +def get_file_result_diff(old_target_file, new_target_file): + old_file_result_map = parse_file_result(parser_include_ast(global_old_dir, [old_target_file])) + new_file_result_map = parse_file_result(parser_include_ast(global_new_dir, [new_target_file])) + all_key_list = old_file_result_map.keys() | new_file_result_map.keys() + for key in all_key_list: + diff_info_list.extend(judgment_entrance(old_file_result_map.get(key), new_file_result_map.get(key))) + + +def del_file(dir_path): + file_list = os.listdir(dir_path) + for i in file_list: + if get_file_ext(i) != '.h' and get_file_ext(i) != '': + continue + file_path = os.path.join(dir_path, i) + if os.path.isdir(file_path): + del_file(file_path) + if get_file_ext(i) == '.h': + result_map = parse_file_result(parser_include_ast(global_old_dir, [file_path])) + for old_info in result_map.values(): + diff_info_list.extend(judgment_entrance(old_info, None)) + + +def add_file(dir_path): + file_list = os.listdir(dir_path) + for i in file_list: + if get_file_ext(i) != '.h' and get_file_ext(i) != '': + continue + file_path = os.path.join(dir_path, i) + if os.path.isdir(file_path): + add_file(file_path) + if get_file_ext(i) == '.h': + result_map = parse_file_result(parser_include_ast(global_new_dir, [file_path])) + for new_info in result_map.values(): + diff_info_list.extend(judgment_entrance(None, new_info)) + + +def parse_file_result(result): + result_map = {} + for root_node in result: + children_list = root_node['children'] + for children in children_list: + if children["name"] == '': + continue + result_map.setdefault(f'{children["name"]}-{children["kind"]}', children) + del root_node['children'] + result_map.setdefault(f'{root_node["name"]}-{root_node["kind"]}', root_node) + return result_map