• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# Copyright (c) 2021 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 sys
17import os
18import hashlib
19import argparse
20
21
22class InterfaceMgr:
23    __max_buf = 1024 * 1024
24
25    def get_file_sha256(self, filename: str):
26        hash_value = None
27        if os.path.isfile(filename):
28            sha256obj = hashlib.sha256()
29            try:
30                with open(filename, 'rb') as f:
31                    while True:
32                        buf = f.read(self.__max_buf)
33                        if not buf:
34                            break
35                        sha256obj.update(buf)
36                    hash_value = sha256obj.hexdigest()
37            except OSError as err:
38                sys.stdout.write("read file failed. {}".format(err))
39                return ""
40        return str(hash_value)
41
42    def get_header_files(self, file_dir: str) -> list:
43        h_files = []
44        for path, _, files in os.walk(file_dir):
45            for file in files:
46                if file.endswith('.h'):
47                    x_file = os.path.relpath(os.path.join(path, file),
48                                             file_dir)
49                    h_files.append(x_file)
50        return h_files
51
52    def gen_sig_file_by_subsystem(self, subsystem_sdk_out_dir: str,
53                                  sig_file_gen_dir: str):
54        if not os.path.exists(subsystem_sdk_out_dir) or not os.path.isdir(
55                subsystem_sdk_out_dir):
56            raise Exception(
57                "subsystem sdk out dir '{}' not exist or not dir".format(
58                    subsystem_sdk_out_dir))
59
60        module_list = os.listdir(subsystem_sdk_out_dir)
61        for module_name in module_list:
62            module_dir = os.path.join(subsystem_sdk_out_dir, module_name)
63            if not os.path.exists(module_dir) or not os.path.isdir(module_dir):
64                continue
65            header_files = self.get_header_files(module_dir)
66            if not header_files:
67                continue
68            check_content = []
69            for h_file in header_files:
70                file_sha256 = self.get_file_sha256(
71                    os.path.join(module_dir, h_file))
72                check_content.append('{} {}'.format(h_file, file_sha256))
73
74            check_file = os.path.join(sig_file_gen_dir, module_name,
75                                      'check.txt')
76            file_dir = os.path.dirname(os.path.abspath(check_file))
77            if not os.path.exists(file_dir):
78                os.makedirs(file_dir, exist_ok=True)
79
80            # sort check file content
81            check_content.sort()
82            with open(check_file, 'w') as output_file:
83                output_file.write('\n'.join(check_content))
84                output_file.flush()
85
86    def _gen_checkfile(self, check_file_dir: str, target_type_dir: str, target_type: str):
87        subsystem_list = os.listdir(target_type_dir)
88        for subsystem_name in subsystem_list:
89            subsystem_dir = os.path.join(target_type_dir, subsystem_name)
90            if not os.path.isdir(subsystem_dir) or target_type.startswith(
91                    '.'):
92                continue
93            self.gen_sig_file_by_subsystem(subsystem_name, check_file_dir)
94
95    def gen_interface_checkfile(self, sdk_base_dir, check_file_dir):
96        if not os.path.isdir(sdk_base_dir):
97            raise Exception(
98                'sdk base dir [{}] does not exist.'.format(sdk_base_dir))
99
100        target_type_allowlist = ['ohos-arm64']
101        target_types = os.listdir(sdk_base_dir)
102        for target_type in target_types:
103            target_type_dir = os.path.join(sdk_base_dir, target_type)
104            if not os.path.isdir(target_type_dir) or target_type.startswith(
105                    '.'):
106                continue
107
108            if target_type == 'java':
109                continue
110
111            if target_type not in target_type_allowlist:
112                raise Exception('target type is incorrect.')
113
114            self._gen_checkfile(check_file_dir, target_type_dir, target_type)
115
116    def check(self, check_file_dir: str, subsystem_sdk_dir: str, subsystem_name: str,
117              module_name: str):
118        check_file = os.path.join(check_file_dir, subsystem_name, module_name,
119                                  'check.txt')
120        if not os.path.isfile(check_file):
121            raise Exception(
122                '[{}:{}] interface check failed. file [{}] does not exist.'.
123                format(subsystem_name, module_name, check_file))
124
125        check_value = {}
126        with open(check_file, 'r') as f:
127            for line in f.readlines():
128                values = line.rstrip('\n').split(' ')
129                check_value[values[0]] = values[1]
130
131        module_dir = os.path.join(subsystem_sdk_dir, module_name)
132        header_files = self.get_header_files(module_dir)
133        if len(check_value) != len(header_files):
134            raise Exception(('[{}:{}] interface check failed. '
135                             'the number of files is different.').format(
136                                 subsystem_name, module_name))
137
138        for h_file in header_files:
139            file_sha256 = self.get_file_sha256(os.path.join(
140                module_dir, h_file))
141            if check_value.get(h_file) != file_sha256:
142                raise Exception(
143                    '[{}:{}] interface check failed. file [{}] has changed.'.
144                    format(subsystem_name, module_name, h_file))
145
146
147def main():
148    parser = argparse.ArgumentParser()
149    parser.add_argument('--generate', dest='generate', action='store_true')
150    parser.set_defaults(generate=False)
151    parser.add_argument('--sdk-base-dir', help='', required=True)
152    parser.add_argument('--check_file_dir', help='', required=True)
153    args = parser.parse_args()
154
155    if args.generate:
156        interface_mgr = InterfaceMgr()
157        interface_mgr.gen_interface_checkfile(args.sdk_base_dir,
158                                              args.check_file_dir)
159    else:
160        sys.stdout.write('Usage: interface_mgr.py --generate '
161                         '--sdk-base-dir SDK_BASE_DIR '
162                         '--check_file_dir CHECK_FILE_DIR')
163        sys.stdout.flush()
164    return 0
165
166
167if __name__ == '__main__':
168    sys.exit(main())
169