From 4333530db70b72c1e89e9f9749468c0f96e7bd18 Mon Sep 17 00:00:00 2001 From: jwx1102601 Date: Mon, 11 Mar 2024 10:41:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=BC=8F=E6=A0=87=E6=A3=80=E6=B5=8B=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E4=BB=A3=E7=A0=81=E5=8A=9F=E8=83=BD=E6=80=A7=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jwx1102601 --- build-tools/api_label_detection/README.en.md | 30 ----- build-tools/api_label_detection/README.md | 31 ----- build-tools/api_label_detection/README_zh.md | 32 ++++++ .../api_label_detection/src/bin/config.py | 62 +++++++++- .../{detection.py => detection_label.py} | 108 ++++++++++++------ build-tools/api_label_detection/src/main.py | 24 ++++ .../src/typedef/detection.py | 11 ++ .../src/utils/constants.py | 9 +- .../api_label_detection/src/utils/util.py | 13 ++- 9 files changed, 213 insertions(+), 107 deletions(-) delete mode 100644 build-tools/api_label_detection/README.en.md delete mode 100644 build-tools/api_label_detection/README.md create mode 100644 build-tools/api_label_detection/README_zh.md rename build-tools/api_label_detection/src/coreImpl/{detection.py => detection_label.py} (61%) diff --git a/build-tools/api_label_detection/README.en.md b/build-tools/api_label_detection/README.en.md deleted file mode 100644 index 1ff261d95..000000000 --- a/build-tools/api_label_detection/README.en.md +++ /dev/null @@ -1,30 +0,0 @@ -# missing _mark _detection - -#### Description -漏标检查 - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - diff --git a/build-tools/api_label_detection/README.md b/build-tools/api_label_detection/README.md deleted file mode 100644 index 48da59b7b..000000000 --- a/build-tools/api_label_detection/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# missing _mark _detection - -#### 介绍 -漏标检查 - -#### 软件架构 -软件架构说明 - - -#### 安装教程 - -1. xxxx -2. xxxx -3. xxxx - -#### 使用说明 - -1. xxxx -2. xxxx -3. xxxx - -#### 参与贡献 - -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request - - -#### 特技 - diff --git a/build-tools/api_label_detection/README_zh.md b/build-tools/api_label_detection/README_zh.md new file mode 100644 index 000000000..a028f6321 --- /dev/null +++ b/build-tools/api_label_detection/README_zh.md @@ -0,0 +1,32 @@ +# 元服务API集标签检测工具 + +## 简介 +对于元服务标签@atomicservice的漏标误标场景做出识别,辅助API标签排查,将不符合规定标签详情信息汇总至Excel表格中输出 + +## 目录 + +``` +├─src #存放源码 +└─test #本地运行使用文件 +``` + +## 环境 + +1)python-3.11.4-amd64 + +2)PyCharm Community Edition 2023.2 + +3)需要把src目录设置为sources root(找到src目录,点击右键,将目标标记为里面) + +4)在interface_sdk-js目录下运行的是src目录下的mian.py文件 + +## 运行 + +检测工具内置在 ‘基础api解析工具’中,通过命令行形式运行。具体命令格式为 + +``` +python 检测工具main函数位置 -N 工具名称 -P 基础api解析工具结果json文件地址 -O 输Excel出地址 + +例如:python E:\\api_label_detection\\src\\main.py -N detection -P E:\\collect_2024_02_29.json -O D:\\error.xlsx +``` + diff --git a/build-tools/api_label_detection/src/bin/config.py b/build-tools/api_label_detection/src/bin/config.py index 9ce3cf500..7228b64fd 100644 --- a/build-tools/api_label_detection/src/bin/config.py +++ b/build-tools/api_label_detection/src/bin/config.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (c) 2023 Huawei Device Co., Ltd. +# Copyright (c) 2024 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 @@ -13,4 +13,64 @@ # See the License for the specific language governing permissions and # limitations under the License. +import enum +from coreImpl import detection_label + + +class ToolNameType(enum.Enum): + DETECTION = 'detection' + + +tool_name_type_set = [ + member.value for name_tool, + member in ToolNameType.__members__.items() +] + + +class FormatType(enum.Enum): + JSON = 'json' + EXCEL = 'excel' + + +format_set = [ + member.value for name_format, + member in FormatType.__members__.items() +] + + +def run_tools(options): + tool_name = options.tool_name + if tool_name == ToolNameType["DETECTION"].value: + detection_label.detection_label(options.result_json_path, options.output_path) + + +class Config(object): + name = 'parser' + version = '0.1.0' + description = 'Compare the parser the NDKS' + commands = [ + { + "name": "--tool-name", + "abbr": "-N", + "required": True, + "choices": tool_name_type_set, + "type": str, + "default": ToolNameType["DETECTION"], + "help": "工具名称" + }, + { + "name": "--result-json-path", + "abbr": "-P", + "required": True, + "type": str, + "help": "解析结果json文件路径" + }, + { + "name": "--output-path", + "abbr": "-O", + "required": False, + "type": str, + "help": "输出路径" + } + ] diff --git a/build-tools/api_label_detection/src/coreImpl/detection.py b/build-tools/api_label_detection/src/coreImpl/detection_label.py similarity index 61% rename from build-tools/api_label_detection/src/coreImpl/detection.py rename to build-tools/api_label_detection/src/coreImpl/detection_label.py index 03f6d60aa..8d3788ef1 100644 --- a/build-tools/api_label_detection/src/coreImpl/detection.py +++ b/build-tools/api_label_detection/src/coreImpl/detection_label.py @@ -13,10 +13,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -from src.utils.util import (get_start_characters, get_remaining_characters, json_file_data, label_type_conversion, - get_check_labels, generate_excel, get_position_information, set_label_to_result) -from src.utils.constants import mutex_label_dist, contrast_function, label_name_dist -from src.typedef.detection import Output, ErrorMessage, ErrorType +from utils.util import (get_start_characters, get_remaining_characters, json_file_data, label_type_conversion, + get_check_labels, generate_excel, get_position_information, + set_label_to_result, get_js_doc_info) +from utils.constants import mutex_label_dist, contrast_function, label_name_dist, one_to_many_function +from typedef.detection import Output, ErrorMessage, ErrorType + result_list = [] @@ -35,19 +37,24 @@ def judgement_dict_data(result, result_key): dict_keys = dict_data.keys() if 'childApis' in dict_keys: # 递归处理child judgement_dict_data(dict_data, 'childApis') - # 命令控制是否校验成对函数漏标 - if 1 == 1: - paired_function_omission_label(my_dict) + #校验成对函数漏标 + paired_function_omission_label(my_dict) def enum_label_detection(parent_enum_info: dict): + if 'jsDocInfos' not in parent_enum_info: + return parent_js_doc_info = get_js_doc_info(parent_enum_info['jsDocInfos']) + if parent_js_doc_info is None: + return if not parent_js_doc_info['isAtomicService']: return children_list = parent_enum_info['childApis'] count = 0 for child_info in children_list: child_doc_info = get_js_doc_info(child_info['jsDocInfos']) + if child_doc_info is None: + continue if child_doc_info['isAtomicService']: count = count + 1 if count == 0: @@ -67,55 +74,76 @@ def paired_function_omission_label(my_dict: dict): def is_pairing_function(defined_text, my_dict: dict): - api_type = my_dict[defined_text]['apiType'] + target_api_info = my_dict[defined_text] + api_type = target_api_info['apiType'] if api_type != 'Method': return False - start = get_start_characters(my_dict[defined_text]['apiName']) + start = get_start_characters(target_api_info['apiName']) return start in contrast_function.keys() def pairing(defined_text, my_dict, filter_duplicates_dist): - four_twin_list = ['off', 'on', 'emit', 'once'] function_name = my_dict[defined_text]['apiName'] start = get_start_characters(function_name) api_name_list = [] # 4个中的其中之一 - if start in four_twin_list: - dismantle_four_twin(my_dict, four_twin_list, start, function_name, api_name_list) + if start in one_to_many_function: + dismantle_one_to_many(my_dict, start, function_name, api_name_list) else: dismantle_ordinary(start, my_dict, function_name, api_name_list) # 找到对应的函数 if len(api_name_list) != 0: - ff = my_dict[defined_text] + function_target_data = my_dict[defined_text] for api_name in api_name_list: api_info = my_dict[api_name] - handling_missing_labels(ff, api_info, filter_duplicates_dist) + handling_missing_labels(function_target_data, api_info, filter_duplicates_dist) -def dismantle_four_twin(my_dict: dict, four_twin_list, start, function_name, api_name_list): - for func in my_dict: - if get_start_characters(my_dict[func]['apiName']) in four_twin_list: - if (get_remaining_characters(get_start_characters(my_dict[func]['apiName']), my_dict[func]['apiName']) +def dismantle_one_to_many(my_dict: dict, start, function_name, api_name_list): + for defined_text in my_dict: + api_name = my_dict[defined_text]['apiName'] + if get_start_characters(api_name) in one_to_many_function: + if (get_remaining_characters(get_start_characters(api_name), api_name) == get_remaining_characters(start, function_name)): - api_name_list.append(func) + api_name_list.append(defined_text) def dismantle_ordinary(start, my_dict: dict, function_name, api_name_list): relative_function = contrast_function.get(start) - for api_name in my_dict: - if get_start_characters(my_dict[api_name]['apiName']) == relative_function: - if (get_remaining_characters(relative_function, my_dict[api_name]['apiName']) + for defined_text in my_dict: + api_name = my_dict[defined_text]['apiName'] + if get_start_characters(api_name) == relative_function: + if (get_remaining_characters(relative_function, api_name) == get_remaining_characters(start, function_name)): - api_name_list.append(api_name) + api_name_list.append(defined_text) # 处理成对函数漏标问题 def handling_missing_labels(function_target_data: dict, function_relative_data: dict, filter_duplicates_dist): - target_doc_infos = function_target_data['jsDocInfos'] - relative_doc_infos = function_relative_data['jsDocInfos'] - target_doc_info = target_doc_infos[len(target_doc_infos) - 1] - relative_doc_info = relative_doc_infos[len(relative_doc_infos) - 1] + #目标函数与相对函数Doc信息都为空,直接返回不做判断 + if 'jsDocInfos' not in function_target_data and 'jsDocInfos' not in function_relative_data: + return + #目标函数Doc信息为空,相对函数标记的标签全部为目标函数漏标 + if 'jsDocInfos' not in function_target_data: + relative_doc_info = get_js_doc_info(function_relative_data['jsDocInfos']) + if relative_doc_info is None: + return + #判断相对函数中标记的标签 + one_function_is_empty(function_relative_data, filter_duplicates_dist) + return + #相对函数Doc信息为空,目标函数标记的标签全部为相对函数漏标 + if 'jsDocInfos' not in function_relative_data: + relative_doc_info = get_js_doc_info(function_target_data['jsDocInfos']) + if relative_doc_info is None: + return + # 判断相对函数中标记的标签 + one_function_is_empty(function_target_data, filter_duplicates_dist) + return + + #目标函数和相对函数Doc信息都不为空 + target_doc_info = get_js_doc_info(function_target_data['jsDocInfos']) + relative_doc_info = get_js_doc_info(function_relative_data['jsDocInfos']) target_label_info = get_check_labels(target_doc_info) relative_label_info = get_check_labels(relative_doc_info) diff = target_label_info.keys() & relative_label_info @@ -129,6 +157,19 @@ def handling_missing_labels(function_target_data: dict, function_relative_data: get_label_exclusivity_results(function_target_data, filter_duplicates_dist, val) +def one_function_is_empty(function_info: dict, filter_duplicates_dist): + doc_info = get_js_doc_info(function_info['jsDocInfos']) + if doc_info is None: + return + #判断需要校验的标签 + if doc_info['isAtomicService']: + get_label_exclusivity_results(function_info, filter_duplicates_dist, 'isAtomicService') + if doc_info['isForm']: + get_label_exclusivity_results(function_info, filter_duplicates_dist, 'isForm') + if doc_info['isCrossPlatForm']: + get_label_exclusivity_results(function_info, filter_duplicates_dist, 'isCrossPlatForm') + + def get_label_exclusivity_results(relative_data: dict, filter_duplicates_dist, val): defined_text = relative_data['definedText'] + val if defined_text not in filter_duplicates_dist: @@ -163,16 +204,9 @@ def is_label_consistent(doc_info: dict, label, mutex_label_list, api_info): result_list.append(result) -def get_js_doc_info(js_doc_info_list: list): - if len(js_doc_info_list) > 0: - return js_doc_info_list[len(js_doc_info_list) - 1] - return None - - # 按装订区域中的绿色按钮以运行脚本。 -if __name__ == '__main__': - path = r'E:\python_workspace\collect_0_0.json' - data = json_file_data(path) +def detection_label(result_json_path, output_path): + data = json_file_data(result_json_path) for key in data: # 代表每个ts文件 judgement_dict_data(data, key) - generate_excel(result_list, '') + generate_excel(result_list, output_path) diff --git a/build-tools/api_label_detection/src/main.py b/build-tools/api_label_detection/src/main.py index e4d49076e..a81836b87 100644 --- a/build-tools/api_label_detection/src/main.py +++ b/build-tools/api_label_detection/src/main.py @@ -12,3 +12,27 @@ # 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 argparse +from bin import config + + +def main_function(): + parser = argparse.ArgumentParser( + prog=config.Config.name, description=config.Config.description) + for command in config.Config.commands: + arg_abbr = command.get("abbr") + arg_name = command.get("name") + arg_choices = command.get("choices") + arg_required = (True if command.get("required") else False) + arg_type = command.get("type") + default = command.get("default") + arg_help = command.get("help") + parser.add_argument(arg_abbr, arg_name, choices=arg_choices, + required=arg_required, type=arg_type, default=default, help=arg_help) + + config.run_tools(parser.parse_args()) + + +if __name__ == '__main__': + main_function() diff --git a/build-tools/api_label_detection/src/typedef/detection.py b/build-tools/api_label_detection/src/typedef/detection.py index d1e35e6d1..77c784b58 100644 --- a/build-tools/api_label_detection/src/typedef/detection.py +++ b/build-tools/api_label_detection/src/typedef/detection.py @@ -36,9 +36,20 @@ class ErrorMessage(enum.Enum): RELATIVE_LABEL = 'Functions that appear in pairs,[$] function missing [&] tag' ENUM_LABEL = ('The enumeration type [$] is labeled with [&], but none of the enumeration ' 'values are labeled with this label') + PARENT_HAVE_METHOD_NO = '[$] has a [&] label, but none of its methods have a [&] label' + METHOD_HAVE_PARENT_NO = '[$]does not have [&] label,but the methods below it has [&] label' + METHOD_HAVE_INPUT_PARAM_NO = 'functions have [&] label, but the param do not have [&] label' + METHOD_HAVE_OUTPUT_PARAM_NO = 'functions have [&] label, but the return value has no [&] label' + METHOD_HAVE_OBJ_NO = 'functions have [&] label, but anonymous objects do not have [&] label' class ErrorType(enum.Enum): MUTEX_LABEL = 'mutex_label' ENUM_LABEL = 'enum_value_missing_label' RELATIVE_LABEL = 'paired_function_omission_label' + PARENT_NO_TAG = '$_missing_label' + CHILD_NO_TAG = 'method_missing_label' + PARAM_NO_TAG = 'param_missing_label' + RETURN_NO_TAG = 'return_missing_label' + OBJ_NO_TAG = 'anonymous_object_missing_label' + diff --git a/build-tools/api_label_detection/src/utils/constants.py b/build-tools/api_label_detection/src/utils/constants.py index 7aad5af72..4765f2a18 100644 --- a/build-tools/api_label_detection/src/utils/constants.py +++ b/build-tools/api_label_detection/src/utils/constants.py @@ -1,7 +1,6 @@ #!/usr/bin/env python -# coding=utf-8 -############################################## -# Copyright (c) 2021-2022 Huawei Device Co., Ltd. +# -*- coding: utf-8 -*- +# Copyright (c) 2024 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 @@ -13,7 +12,6 @@ # 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. -############################################## mutex_label_dist = { @@ -21,6 +19,9 @@ mutex_label_dist = { } +one_to_many_function = ['off', 'on', 'emit', 'once'] + + label_name_dist = { 'isAtomicService': '@atomicservice', 'deprecatedVersion': '@deprecated', diff --git a/build-tools/api_label_detection/src/utils/util.py b/build-tools/api_label_detection/src/utils/util.py index 687bcf49d..8971a97f3 100644 --- a/build-tools/api_label_detection/src/utils/util.py +++ b/build-tools/api_label_detection/src/utils/util.py @@ -1,7 +1,6 @@ #!/usr/bin/env python -# coding=utf-8 -############################################## -# Copyright (c) 2021-2022 Huawei Device Co., Ltd. +# -*- coding: utf-8 -*- +# Copyright (c) 2024 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 @@ -13,7 +12,6 @@ # 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 json import re @@ -82,3 +80,10 @@ def get_position_information(pos: dict): def set_label_to_result(message, label, mutex_label): return message.replace('$', label).replace('&', mutex_label) + + +def get_js_doc_info(js_doc_info_list: list): + if len(js_doc_info_list) > 0: + return js_doc_info_list[len(js_doc_info_list) - 1] + return None +