• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15import { ApiResultSimpleInfo, ApiResultMessage, ApiBaseInfo, checkEntryType } from '../../typedef/checker/result_type';
16import { Check } from './src/api_check_plugin';
17import { LogUtil } from '../../utils/logUtil';
18import { GenerateFile } from '../../utils/checkUtils';
19import { compositiveResult, compositiveLocalResult, apiCheckResult, hierarchicalRelationsSet } from '../../utils/checkUtils';
20import { DOC, DEFINE, CHANEGE } from './config/api_check_config.json';
21import { ApiChangeCheck } from './src/check_api_diff';
22
23/**
24 * local entrance
25 */
26export class LocalEntry {
27
28  static checkEntryLocal(checkParam: checkEntryType): ApiResultMessage[] {
29    let allResult: ApiResultMessage[] = apiCheckResult;
30    try {
31      Check.scanEntry(checkParam.filePathArr, checkParam.prId);
32      const incrementResult: ApiResultSimpleInfo[] = LocalEntry.filterIncrementResult(compositiveResult, checkParam.isIncrement);
33      LocalEntry.maskAlarm(incrementResult, checkParam.fileRuleArr);
34    } catch (error) {
35      LogUtil.e('API_CHECK_ERROR', error);
36    } finally {
37      GenerateFile.writeFile(apiCheckResult, checkParam.output, {});
38      if (checkParam.isOutExcel === 'true') {
39        GenerateFile.writeExcelFile(apiCheckResult);
40      }
41    }
42    return allResult;
43  }
44
45  /**
46   * 过滤增量检查结果
47   *
48   * @param {ApiResultSimpleInfo[]} allResultInfo 所有apicheck结果
49   * @param {boolean} isIncrement 是否为命令配置的增量检查,默认为true
50   * @return {*}  {ApiResultSimpleInfo[]}
51   * @memberof LocalEntry
52   */
53  static filterIncrementResult(allResultInfo: ApiResultSimpleInfo[], isIncrement: boolean): ApiResultSimpleInfo[] {
54    // 不需要增量检查或者diff数据为空
55    if (!isIncrement || hierarchicalRelationsSet.size === 0) {
56      return allResultInfo;
57    }
58    return allResultInfo.filter((resultItem: ApiResultSimpleInfo) => {
59      return !Boolean(process.env.IS_INCREMENT_CHECK) || LocalEntry.hasHierarchicalRelations(resultItem);
60    });
61  }
62
63  static hasHierarchicalRelations(resultItem: ApiResultSimpleInfo): boolean {
64    if (process.env.NODE_ENV === 'development') {
65      return hierarchicalRelationsSet.has(resultItem.hierarchicalRelations);
66    } else if (process.env.NODE_ENV === 'production') {
67      return hierarchicalRelationsSet.has(resultItem.hierarchicalRelations);
68    }
69    return hierarchicalRelationsSet.has(resultItem.hierarchicalRelations);
70  }
71
72  static maskAlarm(allResultInfo: ApiResultSimpleInfo[], fileRuleArr: string[]): void {
73    const localScan: boolean = (fileRuleArr.length === 1 && fileRuleArr[0] === 'all') ? true : false;
74    const apiCheckInfos: Map<string, string> = new Map(Object.entries({ ...DOC, ...DEFINE, ...CHANEGE }));
75    let apiCheckAdmissiveSet: Set<string> = new Set();
76    if (localScan) {
77      apiCheckAdmissiveSet = new Set([...apiCheckInfos.values()]);
78    } else {
79      fileRuleArr.forEach((apiCheckItem: string) => {
80        const apiCheckItemMessage: string | undefined = apiCheckInfos.get(apiCheckItem);
81        if (apiCheckItemMessage) {
82          apiCheckAdmissiveSet.add(apiCheckItemMessage);
83        }
84      });
85    }
86    let allResultInfoSet: Set<ApiResultSimpleInfo> = new Set(allResultInfo);
87    const maskResult: ApiResultSimpleInfo[] = LocalEntry.filterAllResultInfo(allResultInfo,
88      apiCheckInfos, apiCheckAdmissiveSet);
89    maskResult.forEach(resultItem => {
90      const apiBaseInfos: ApiBaseInfo = new ApiBaseInfo();
91      apiBaseInfos
92        .setApiName(resultItem.apiName)
93        .setApiType(resultItem.apiType)
94        .setHierarchicalRelations(resultItem.hierarchicalRelations)
95        .setParentModuleName(resultItem.parentModuleName);
96
97      const apiChecktErrorLog: ApiResultMessage = new ApiResultMessage();
98      apiChecktErrorLog
99        .setFilePath(resultItem.filePath)
100        .setLocation(resultItem.location)
101        .setLevel(resultItem.level)
102        .setType(resultItem.type)
103        .setMessage(resultItem.message)
104        .setMainBuggyCode(resultItem.apiText)
105        .setMainBuggyLine(resultItem.location)
106        .setExtendInfo(apiBaseInfos);
107      apiCheckResult.push(apiChecktErrorLog);
108    });
109  }
110
111  static filterAllResultInfo(allResultInfo: ApiResultSimpleInfo[], apiCheckInfos: Map<string, string>,
112    apiCheckAdmissiveSet: Set<string>): ApiResultSimpleInfo[] {
113    return allResultInfo.filter((resultItem: ApiResultSimpleInfo) => {
114      let resultItemInfo: string = resultItem.message.replace(/API check error of \[.*\]: /g, '');
115      const regex1 = /Prohibited word in \[.*\]:{option}.The word allowed is \[.*\]\./g;
116      const regex2 = /Prohibited word in \[.*\]:{ability} in the \[.*\] file\./g;
117      const regex3 = /please confirm whether it needs to be corrected to a common word./g;
118      const regex4 = /tag does not exist. Please use a valid JSDoc tag./g;
119      const regex5 = /The event name should be named by small hump./g;
120      if (/\d/g.test(resultItemInfo)) {
121        resultItemInfo = resultItemInfo.replace(/\d+/g, '1');
122      }
123      if (regex1.test(resultItemInfo)) {
124        resultItemInfo = JSON.stringify(apiCheckInfos.get('API_DEFINE_NAME_01')).replace(/\"/g, '');
125      }
126      if (regex2.test(resultItemInfo)) {
127        resultItemInfo = JSON.stringify(apiCheckInfos.get('API_DEFINE_NAME_02')).replace(/\"/g, '');
128      }
129      if (regex3.test(resultItemInfo)) {
130        resultItemInfo = resultItemInfo.replace(/\{.*\}/g, '{XXXX}');
131      }
132      if (regex4.test(resultItemInfo)) {
133        resultItemInfo = resultItemInfo.replace(/\[.*\]/g, '[XXXX]');
134      }
135      if (regex5.test(resultItemInfo)) {
136        resultItemInfo = resultItemInfo.replace(/\[.*\]/g, '[XXXX]');
137      }
138      if (/This name \[.*\] should be named by/g.test(resultItemInfo)) {
139        resultItemInfo = resultItemInfo.replace(/\[.*\]/g, '[XXXX]');
140      }
141      if (apiCheckAdmissiveSet.has(resultItemInfo)) {
142        const key: string = LocalEntry.filterApiCheckInfos(apiCheckInfos, resultItemInfo);
143        if (key !== '') {
144          resultItem.setType(key);
145        }
146      }
147      return apiCheckAdmissiveSet.has(resultItemInfo);
148    });
149  }
150
151  static filterApiCheckInfos(apiCheckInfos: Map<string, string>, resultItemInfo: string): string {
152    for (let [key, value] of apiCheckInfos.entries()) {
153      if (value === resultItemInfo) {
154        return key;
155      }
156    }
157    return '';
158  }
159
160  static apiChangeCheckEntryLocal(checkParam: checkEntryType): ApiResultMessage[] {
161    let apiChangeCheckResult: ApiResultMessage[] = apiCheckResult;
162    try {
163      ApiChangeCheck.checkApiChange(checkParam.prId);
164      LocalEntry.maskAlarm(compositiveResult, checkParam.fileRuleArr);
165    } catch (error) {
166      LogUtil.e('API_CHECK_ERROR', error);
167    } finally {
168      GenerateFile.writeFile(apiCheckResult, checkParam.output, {});
169      if (checkParam.isOutExcel === 'true') {
170        GenerateFile.writeExcelFile(apiCheckResult);
171      }
172    }
173    return apiChangeCheckResult;
174  }
175}
176