15f9996aaSopenharmony_ci#!/usr/bin/env python3
25f9996aaSopenharmony_ci#-*- coding: UTF-8 -*-
35f9996aaSopenharmony_ci# Copyright (c) 2021 Huawei Device Co., Ltd.
45f9996aaSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
55f9996aaSopenharmony_ci# you may not use this file except in compliance with the License.
65f9996aaSopenharmony_ci# You may obtain a copy of the License at
75f9996aaSopenharmony_ci#
85f9996aaSopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
95f9996aaSopenharmony_ci#
105f9996aaSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
115f9996aaSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
125f9996aaSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135f9996aaSopenharmony_ci# See the License for the specific language governing permissions and
145f9996aaSopenharmony_ci# limitations under the License.
155f9996aaSopenharmony_ci
165f9996aaSopenharmony_ci"""
175f9996aaSopenharmony_ci
185f9996aaSopenharmony_ciUsage: get_warnings.py --build-log-file out/phone-release/build.log \
195f9996aaSopenharmony_ci               --warning-out-file out/phone-release/warning_list.txt
205f9996aaSopenharmony_ci
215f9996aaSopenharmony_ciGenerate the project notice files, including both text and xml files.
225f9996aaSopenharmony_ci
235f9996aaSopenharmony_ci"""
245f9996aaSopenharmony_ci
255f9996aaSopenharmony_ciimport argparse
265f9996aaSopenharmony_ciimport os
275f9996aaSopenharmony_ciimport sys
285f9996aaSopenharmony_ciimport re
295f9996aaSopenharmony_ciimport subprocess
305f9996aaSopenharmony_ci
315f9996aaSopenharmony_ci
325f9996aaSopenharmony_cidef _do_uniq(infile: str, outfile: str):
335f9996aaSopenharmony_ci    subprocess.call(['sort', '-u', infile, '-o', outfile], shell=False)
345f9996aaSopenharmony_ci
355f9996aaSopenharmony_ci
365f9996aaSopenharmony_cidef _pick_line(line_info) -> bool:
375f9996aaSopenharmony_ci    result = False
385f9996aaSopenharmony_ci    parser_keys = [
395f9996aaSopenharmony_ci        ": Warning", ": warning", "warning:", "Warning:", "WARNING:"
405f9996aaSopenharmony_ci    ]
415f9996aaSopenharmony_ci    for _key in parser_keys:
425f9996aaSopenharmony_ci        if len(re.findall(_key, line_info, re.S)) >= 1:
435f9996aaSopenharmony_ci            result = True
445f9996aaSopenharmony_ci            break
455f9996aaSopenharmony_ci    return result
465f9996aaSopenharmony_ci
475f9996aaSopenharmony_ci
485f9996aaSopenharmony_cidef _parse(in_name: str, out_name: str, prj_dir: str) -> bool:
495f9996aaSopenharmony_ci    if not os.path.exists(in_name):
505f9996aaSopenharmony_ci        print("warning: build log file {} is not exists.".format(in_name))
515f9996aaSopenharmony_ci        return False
525f9996aaSopenharmony_ci
535f9996aaSopenharmony_ci    with open(in_name, "r", encoding='utf-8', errors='ignore') as in_fd:
545f9996aaSopenharmony_ci        os.makedirs(os.path.dirname(out_name), exist_ok=True)
555f9996aaSopenharmony_ci        with open(out_name, "w") as out_fd:
565f9996aaSopenharmony_ci            while True:
575f9996aaSopenharmony_ci                line_info = in_fd.readline()
585f9996aaSopenharmony_ci                line_info = line_info.replace("\r", "")
595f9996aaSopenharmony_ci                if line_info == "":
605f9996aaSopenharmony_ci                    break
615f9996aaSopenharmony_ci                # Solve the non-standard printing in kernel compilation --begin
625f9996aaSopenharmony_ci                if (line_info.find("kernel/linux-") >
635f9996aaSopenharmony_ci                        1) and (": warning:" in line_info):
645f9996aaSopenharmony_ci                    line_info = line_info[line_info.find("kernel/linux-"):]
655f9996aaSopenharmony_ci                # Solve the non-standard printing in kernel compilation --end
665f9996aaSopenharmony_ci                if _pick_line(line_info):
675f9996aaSopenharmony_ci                    while True:
685f9996aaSopenharmony_ci                        if line_info.startswith("../"):
695f9996aaSopenharmony_ci                            line_info = line_info[3:]
705f9996aaSopenharmony_ci                        elif line_info.startswith("./"):
715f9996aaSopenharmony_ci                            line_info = line_info[2:]
725f9996aaSopenharmony_ci                        elif line_info.startswith("\""):
735f9996aaSopenharmony_ci                            line_info = line_info[1:]
745f9996aaSopenharmony_ci                        elif line_info.startswith(":"):
755f9996aaSopenharmony_ci                            line_info = line_info[1:]
765f9996aaSopenharmony_ci                        elif line_info.startswith(" "):
775f9996aaSopenharmony_ci                            line_info = line_info[1:]
785f9996aaSopenharmony_ci                        else:
795f9996aaSopenharmony_ci                            break
805f9996aaSopenharmony_ci                    # solving relative path
815f9996aaSopenharmony_ci                    templist = line_info.split(":")
825f9996aaSopenharmony_ci                    templist[0] = os.path.abspath(templist[0])
835f9996aaSopenharmony_ci                    templist[0] = templist[0].replace(prj_dir + "/",
845f9996aaSopenharmony_ci                                                      "").strip()
855f9996aaSopenharmony_ci                    temp = ":"
865f9996aaSopenharmony_ci                    line_info = temp.join(templist)
875f9996aaSopenharmony_ci
885f9996aaSopenharmony_ci                    out_fd.write(line_info)
895f9996aaSopenharmony_ci                    out_fd.write("\r\n")
905f9996aaSopenharmony_ci    return True
915f9996aaSopenharmony_ci
925f9996aaSopenharmony_ci
935f9996aaSopenharmony_cidef _get_warn(log_file: str, warn_file: str, prj_dir: str):
945f9996aaSopenharmony_ci    if not os.path.exists(os.path.dirname(warn_file)):
955f9996aaSopenharmony_ci        os.makedirs(os.path.dirname(warn_file), exist_ok=True)
965f9996aaSopenharmony_ci    if os.path.exists(warn_file):
975f9996aaSopenharmony_ci        os.remove(warn_file)
985f9996aaSopenharmony_ci    temp_out_file = os.path.join(os.path.dirname(warn_file),
995f9996aaSopenharmony_ci                                 'temp_warning.txt')
1005f9996aaSopenharmony_ci    result = _parse(log_file, temp_out_file, prj_dir)
1015f9996aaSopenharmony_ci    if result:
1025f9996aaSopenharmony_ci        _do_uniq(temp_out_file, warn_file)
1035f9996aaSopenharmony_ci    # delete temp file
1045f9996aaSopenharmony_ci    if os.path.exists(temp_out_file):
1055f9996aaSopenharmony_ci        os.remove(temp_out_file)
1065f9996aaSopenharmony_ci
1075f9996aaSopenharmony_ci
1085f9996aaSopenharmony_cidef main(argv) -> int:
1095f9996aaSopenharmony_ci    """parse warning info from build log."""
1105f9996aaSopenharmony_ci    parser = argparse.ArgumentParser()
1115f9996aaSopenharmony_ci    parser.add_argument('--build-log-file', help='log file', required=True)
1125f9996aaSopenharmony_ci    parser.add_argument('--warning-out-file',
1135f9996aaSopenharmony_ci                        help='result file',
1145f9996aaSopenharmony_ci                        required=True)
1155f9996aaSopenharmony_ci    args = parser.parse_args(argv)
1165f9996aaSopenharmony_ci
1175f9996aaSopenharmony_ci    log_file = args.build_log_file
1185f9996aaSopenharmony_ci    warn_file = args.warning_out_file
1195f9996aaSopenharmony_ci    prj_dir = os.getcwd()
1205f9996aaSopenharmony_ci    _get_warn(log_file, warn_file, prj_dir)
1215f9996aaSopenharmony_ci    return 0
1225f9996aaSopenharmony_ci
1235f9996aaSopenharmony_ci
1245f9996aaSopenharmony_ciif __name__ == "__main__":
1255f9996aaSopenharmony_ci    main(sys.argv[1:])
126