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 shutil 19import tarfile 20import optparse 21from util import build_utils 22 23sys.path.append( 24 os.path.abspath(os.path.dirname(os.path.abspath( 25 os.path.dirname(__file__))))) 26from scripts.util.file_utils import read_json_file # noqa: E402 27 28RELEASE_FILENAME = 'README.OpenSource' 29scan_dir_list = ['third_party', 'kernel', 'device', 'drivers'] 30 31 32def _copy_opensource_file(opensource_config_file: str, top_dir: str, package_dir: str) -> bool: 33 if not os.path.exists(opensource_config_file): 34 print("Warning, the opensource config file is not exists.") 35 return False 36 37 src_dir = os.path.dirname(opensource_config_file) 38 dst_dir = os.path.join(package_dir, os.path.relpath(src_dir, top_dir)) 39 40 # copy opensource folder to out dir 41 if os.path.exists(dst_dir): 42 shutil.rmtree(dst_dir) 43 shutil.copytree(src_dir, 44 dst_dir, 45 symlinks=True, 46 ignore=shutil.ignore_patterns('*.pyc', 'tmp*', '.git*')) 47 48 # delete the README.OpenSource file 49 release_file = os.path.join(dst_dir, RELEASE_FILENAME) 50 os.remove(release_file) 51 return True 52 53 54def _parse_opensource_file(opensource_config_file: str) -> bool: 55 if not os.path.exists(opensource_config_file): 56 print("Warning, the opensource config file is not exists.") 57 return False 58 59 opensource_config = read_json_file(opensource_config_file) 60 if opensource_config is None: 61 raise Exception("read opensource config file [{}] failed.".format( 62 opensource_config_file)) 63 64 result = False 65 for info in opensource_config: 66 _license = info.get('License') 67 if _license.count('GPL') > 0 or _license.count('LGPL') > 0: 68 result = True 69 return result 70 71 72def _scan_and_package_code_release(scan_dir: str, top_dir: str, package_dir: str): 73 file_dir_names = os.listdir(scan_dir) 74 for file_dir_name in file_dir_names: 75 file_dir_path = os.path.join(scan_dir, file_dir_name) 76 if os.path.isdir(file_dir_path): 77 _scan_and_package_code_release(file_dir_path, top_dir, package_dir) 78 elif file_dir_path == os.path.join(scan_dir, RELEASE_FILENAME): 79 if _parse_opensource_file(file_dir_path): 80 _copy_opensource_file(file_dir_path, top_dir, package_dir) 81 82 83def _tar_opensource_package_file(options, package_dir: str) -> int: 84 result = -1 85 if os.path.exists(package_dir): 86 try: 87 with tarfile.open(options.output, "w:gz") as tar: 88 tar.add(package_dir, arcname=".") 89 result = 0 90 except IOError as err: 91 raise err 92 return result 93 94 95def main(args) -> int: 96 """generate open source packages to release.""" 97 parser = optparse.OptionParser() 98 build_utils.add_depfile_option(parser) 99 parser.add_option('--output', help='output') 100 parser.add_option('--root-dir', help='source root directory') 101 options, _ = parser.parse_args(args) 102 103 # get the source top directory to be scan 104 top_dir = options.root_dir 105 106 with build_utils.temp_dir() as package_dir: 107 # scan the target dir and copy release code to out/opensource dir 108 dir_list = [os.path.join(top_dir, _dir) for _dir in scan_dir_list] 109 for scan_dir in dir_list: 110 _scan_and_package_code_release(scan_dir, top_dir, package_dir) 111 112 # package the opensource to Code_Opensource.tar.gz 113 if _tar_opensource_package_file(options, package_dir) == 0: 114 print('Generate the opensource package successfully.') 115 else: 116 print('Generate the opensource package failed.') 117 118 return 0 119 120 121if __name__ == '__main__': 122 sys.exit(main(sys.argv[1:])) 123