mirror of
https://gitee.com/openharmony/interface_sdk-js
synced 2024-11-23 07:10:52 +00:00
commit
bc9ef98bf3
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
#### 特技
|
||||
|
32
build-tools/api_label_detection/README_zh.md
Normal file
32
build-tools/api_label_detection/README_zh.md
Normal file
@ -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
|
||||
```
|
||||
|
@ -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": "输出路径"
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -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)
|
@ -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()
|
||||
|
@ -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'
|
||||
|
||||
|
@ -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',
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user