• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# Copyright (c) 2022 Huawei Device Co., Ltd.
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import os
17import re
18from bundle_check.bundle_check_common import BundleCheckTools
19from bundle_check.warning_info import BCWarnInfo
20
21
22class BundleCheckOnline:
23    '''用于检查 bundle.json pr。'''
24
25    @staticmethod
26    def check_diff(diff:dict):
27        '''
28        @func: 根据 diff 部分对 bundle.json 进行静态检查。
29        @parm:
30            ``diff``: 格式化后的字典类型的 diff 文件修改信息。示例:
31                d = {
32                    "path1/bundle.json": [
33                        [line1, "content1"],
34                        [line2, "content2"]
35                    ]
36                }
37        '''
38        diff_dict = {}
39        for file_path in diff:
40            diff_dict[file_path] = []
41            diff_list = diff[file_path]
42            for i in diff_list:
43                if '/third_party_' in file_path and 'name' in i[1]:
44                    continue
45                ret = BundleCheckOnline.check_diff_by_line(i[1])
46                if not ret:
47                    continue
48                line = list(("line" + str(i[0]) + ": " + i[1], ret))
49                if file_path in diff_dict.keys():
50                    diff_dict[file_path].append(line)
51        # trans to list
52        err_list = []
53        for file in diff_dict:
54            for i in diff_dict[file]:
55                row = [file, i[0]]
56                row.extend([BCWarnInfo.CHECK_RULE_2_1, i[1]])
57                err_list.append(row)
58        if err_list:
59            return True, err_list
60        else:
61            return False, err_list
62
63    def check_diff_by_line(line:str) -> str:
64        line = line.strip()
65        match = re.match(r'"(\w+)"\s*:\s*"(.*)"', line)
66        if not match:
67            return ""
68        key = match.group(1)
69        value = match.group(2)
70
71        if key == 'name':
72            return _check_line_name(value)
73        if key == 'version':
74            if len(value) == 0:
75                return BCWarnInfo.VERSION_EMPTY
76            else:
77                return ""
78        if key == 'destPath':
79            if os.path.isabs(value):
80                return BCWarnInfo.SEGMENT_DESTPATH_ABS
81            return ""
82        if key == 'subsystem':
83            if not re.match(r'[a-z]+$', value):
84                return BCWarnInfo.COMPONENT_SUBSYSTEM_LOWCASE
85        if key == 'rom' or key == 'ram':
86            return _check_line_rom_ram(key, value)
87        if key == 'syscap':
88            return _check_line_syscap(value)
89        if key == 'features':
90            if len(value) == 0:
91                return BCWarnInfo.COMPONENT_FEATURES_STRING_EMPTY
92        return ""
93
94
95def _check_line_name(value: str):
96    if not value: # value empty
97        return BCWarnInfo.NAME_EMPTY
98    if value.startswith('//') and ':' in value: # exclude inner_kits:name
99        return ""
100    if ('/' in value) and (not BundleCheckTools.match_bundle_full_name(value)):
101        return BCWarnInfo.NAME_FORMAT_ERROR + \
102            BCWarnInfo.COMPONENT_NAME_FROMAT_LEN
103
104    component_name = value.split('/')[1] if ('/' in value) else value
105    if not BundleCheckTools.match_unix_like_name(component_name):
106        return BCWarnInfo.COMPONENT_NAME_FROMAT
107    return ""
108
109
110def _check_line_version(value):
111    if len(value) < 3:
112        return BCWarnInfo.VERSION_ERROR
113    ohos_root_path = BundleCheckTools.get_root_path()
114    if not ohos_root_path:
115        # when project is not exist, do not raise checking error
116        return ""
117    ohos_version = BundleCheckTools.get_ohos_version(ohos_root_path)
118    if ohos_version and value != ohos_version:
119        return BCWarnInfo.VERSION_ERROR + ' ohos version is: ' + value
120    return ""
121
122
123def _check_line_rom_ram(key, value):
124    if len(value) == 0:
125        return r'"component:rom/ram" 字段不能为空。'
126    num, unit = BundleCheckTools.split_by_unit(value)
127    if num < 0:
128        return '"component:{}" 非数值或者小于等于 0。'.format(key)
129    if unit:
130        unit_types = ["KB", "KByte", "MByte", "MB"]
131        if unit not in unit_types:
132            return '"component:{}" 的单位错误(KB, KByte, MByte, MB,默认为KByte)。'.format(key)
133    return ""
134
135
136def _check_line_syscap(value):
137    if len(value) == 0:
138        return BCWarnInfo.COMPONENT_SYSCAP_STRING_EMPTY
139    match = re.match(r'^SystemCapability(\.[A-Z][a-zA-Z]{1,63}){2,6}$', value)
140    if not match:
141        return BCWarnInfo.COMPONENT_SYSCAP_STRING_FORMAT_ERROR
142    return ""