• 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 argparse
18import os
19import shutil
20
21sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
22from scripts.util.file_utils import read_json_file, write_json_file  # noqa: E402
23from scripts.util import build_utils  # noqa: E402
24
25README_FILE_NAME = 'README.OpenSource'
26LICENSE_CANDIDATES = [
27    'LICENSE',
28    'License',
29    'NOTICE',
30    'Notice',
31    'COPYRIGHT',
32    'Copyright'
33]
34
35
36def is_top_dir(current_dir):
37    return os.path.exists(os.path.join(current_dir, '.gn'))
38
39
40def find_license_recursively(current_dir, default_license):
41    if is_top_dir(current_dir):
42        return default_license
43    for file in ['LICENSE', 'NOTICE', 'License', 'Copyright']:
44        candidate = os.path.join(current_dir, file)
45        if os.path.isfile(os.path.join(current_dir, file)):
46            return os.path.join(candidate)
47    return find_license_recursively(os.path.dirname(current_dir),
48                                    default_license)
49
50
51def find_opensource_recursively(current_dir):
52    if is_top_dir(current_dir):
53        return None
54    candidate = os.path.join(current_dir, README_FILE_NAME)
55    if os.path.isfile(candidate):
56        return os.path.join(candidate)
57    return find_opensource_recursively(os.path.dirname(current_dir))
58
59
60def get_license_from_readme(readme_path):
61    contents = read_json_file(readme_path)
62    if contents is None:
63        raise Exception("Error: failed to read {}.".format(readme_path))
64
65    notice_file = contents[0].get('License File').strip()
66    notice_name = contents[0].get('Name').strip()
67    notice_version = contents[0].get('Version Number').strip()
68    if notice_file is None:
69        raise Exception("Error: value of notice file is empty in {}.".format(
70            readme_path))
71    if notice_name is None:
72        raise Exception("Error: Name of notice file is empty in {}.".format(
73            readme_path))
74    if notice_version is None:
75        raise Exception("Error: Version Number of notice file is empty in {}.".format(
76            readme_path))
77
78    return os.path.join(os.path.dirname(readme_path), notice_file), notice_name, notice_version
79
80
81def do_collect_notice_files(options, depfiles):
82    module_notice_info_list = []
83    module_notice_info = {}
84    notice_file = options.license_file
85    if notice_file:
86        opensource_file = find_opensource_recursively(os.path.abspath(options.module_source_dir))
87        if opensource_file is not None and os.path.exists(opensource_file):
88            notice_file_info = get_license_from_readme(opensource_file)
89            module_notice_info['Software'] = "{} {}".format(notice_file_info[1], notice_file_info[2])
90        else:
91            module_notice_info['Software'] = ""
92    if notice_file is None:
93        readme_path = os.path.join(options.module_source_dir,
94                                   README_FILE_NAME)
95        if os.path.exists(readme_path):
96            depfiles.append(readme_path)
97            notice_file_info = get_license_from_readme(readme_path)
98            notice_file = notice_file_info[0]
99            module_notice_info['Software'] = "{} {}".format(notice_file_info[1], notice_file_info[2])
100
101    if notice_file is None:
102        notice_file = find_license_recursively(options.module_source_dir,
103                                               options.default_license)
104        opensource_file = find_opensource_recursively(os.path.abspath(options.module_source_dir))
105        if opensource_file is not None and os.path.exists(opensource_file):
106            notice_file_info = get_license_from_readme(opensource_file)
107            module_notice_info['Software'] = "{} {}".format(notice_file_info[1], notice_file_info[2])
108        else:
109            module_notice_info['Software'] = ""
110
111    module_notice_info['Path'] = "/{}".format(options.module_source_dir[5:])
112    module_notice_info_list.append(module_notice_info)
113
114    if notice_file:
115        for output in options.output:
116            notice_info_json = '{}.json'.format(output)
117            os.makedirs(os.path.dirname(output), exist_ok=True)
118            os.makedirs(os.path.dirname(notice_info_json), exist_ok=True)
119            if os.path.exists(notice_file):
120                shutil.copy(notice_file, output)
121                write_json_file(notice_info_json, module_notice_info_list)
122            else:
123                build_utils.touch(output)
124                build_utils.touch(notice_info_json)
125        depfiles.append(notice_file)
126
127
128def main(args):
129    args = build_utils.expand_file_args(args)
130
131    parser = argparse.ArgumentParser()
132    build_utils.add_depfile_option(parser)
133
134    parser.add_argument('--license-file', required=False)
135    parser.add_argument('--default-license', required=True)
136    parser.add_argument('--output', action='append', required=False)
137    parser.add_argument('--module-source-dir',
138                        help='source directory of this module',
139                        required=True)
140
141    options = parser.parse_args()
142    depfiles = []
143
144    do_collect_notice_files(options, depfiles)
145    if options.license_file:
146        depfiles.append(options.license_file)
147    build_utils.write_depfile(options.depfile, options.output[0], depfiles)
148
149
150if __name__ == '__main__':
151    sys.exit(main(sys.argv[1:]))
152